@capgo/capacitor-contacts 7.1.1 → 8.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CapgoCapacitorContacts.podspec +1 -1
- package/LICENSE +373 -21
- package/Package.swift +2 -2
- package/README.md +2 -4
- package/android/build.gradle +9 -9
- package/android/src/main/java/app/capgo/contacts/CapacitorContactsPlugin.java +797 -26
- package/ios/Sources/CapacitorContactsPlugin/CapacitorContactsPlugin.swift +509 -16
- package/package.json +15 -15
|
@@ -39,6 +39,8 @@ import java.util.Set;
|
|
|
39
39
|
)
|
|
40
40
|
public class CapacitorContactsPlugin extends Plugin {
|
|
41
41
|
|
|
42
|
+
private final String pluginVersion = "8.0.1";
|
|
43
|
+
|
|
42
44
|
// MARK: - Implemented API surface
|
|
43
45
|
|
|
44
46
|
@PluginMethod
|
|
@@ -193,70 +195,835 @@ public class CapacitorContactsPlugin extends Plugin {
|
|
|
193
195
|
call.resolve(status);
|
|
194
196
|
}
|
|
195
197
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
198
|
+
@PluginMethod
|
|
199
|
+
public void getPluginVersion(PluginCall call) {
|
|
200
|
+
try {
|
|
201
|
+
JSObject ret = new JSObject();
|
|
202
|
+
ret.put("version", pluginVersion);
|
|
203
|
+
call.resolve(ret);
|
|
204
|
+
} catch (Exception e) {
|
|
205
|
+
call.reject("Could not get plugin version", e);
|
|
206
|
+
}
|
|
200
207
|
}
|
|
201
208
|
|
|
209
|
+
// MARK: - Write operations
|
|
210
|
+
|
|
202
211
|
@PluginMethod
|
|
203
212
|
public void createContact(PluginCall call) {
|
|
204
|
-
|
|
213
|
+
if (!hasWritePermission()) {
|
|
214
|
+
call.reject("WRITE_CONTACTS permission not granted.");
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
JSObject options = call.getObject("options", new JSObject());
|
|
219
|
+
JSObject contactData = options.getJSObject("contact");
|
|
220
|
+
if (contactData == null) {
|
|
221
|
+
call.reject("Missing contact data.");
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
try {
|
|
226
|
+
String contactId = insertContact(contactData);
|
|
227
|
+
call.resolve(new JSObject().put("id", contactId));
|
|
228
|
+
} catch (Exception ex) {
|
|
229
|
+
call.reject("Failed to create contact.", null, ex);
|
|
230
|
+
}
|
|
205
231
|
}
|
|
206
232
|
|
|
207
233
|
@PluginMethod
|
|
208
|
-
public void
|
|
209
|
-
|
|
234
|
+
public void updateContactById(PluginCall call) {
|
|
235
|
+
if (!hasWritePermission()) {
|
|
236
|
+
call.reject("WRITE_CONTACTS permission not granted.");
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
JSObject options = call.getObject("options", new JSObject());
|
|
241
|
+
String contactId = options.getString("id");
|
|
242
|
+
JSObject contactData = options.getJSObject("contact");
|
|
243
|
+
|
|
244
|
+
if (contactId == null || contactData == null) {
|
|
245
|
+
call.reject("Missing contact identifier or data.");
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
try {
|
|
250
|
+
updateContact(contactId, contactData);
|
|
251
|
+
call.resolve();
|
|
252
|
+
} catch (Exception ex) {
|
|
253
|
+
call.reject("Failed to update contact.", null, ex);
|
|
254
|
+
}
|
|
210
255
|
}
|
|
211
256
|
|
|
212
257
|
@PluginMethod
|
|
213
258
|
public void deleteContactById(PluginCall call) {
|
|
214
|
-
|
|
259
|
+
if (!hasWritePermission()) {
|
|
260
|
+
call.reject("WRITE_CONTACTS permission not granted.");
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
JSObject options = call.getObject("options", new JSObject());
|
|
265
|
+
String contactId = options.getString("id");
|
|
266
|
+
|
|
267
|
+
if (contactId == null) {
|
|
268
|
+
call.reject("Missing contact identifier.");
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
try {
|
|
273
|
+
ContentResolver resolver = getContext().getContentResolver();
|
|
274
|
+
Uri contactUri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, Long.parseLong(contactId));
|
|
275
|
+
int rowsDeleted = resolver.delete(contactUri, null, null);
|
|
276
|
+
if (rowsDeleted > 0) {
|
|
277
|
+
call.resolve();
|
|
278
|
+
} else {
|
|
279
|
+
call.reject("Contact not found or could not be deleted.");
|
|
280
|
+
}
|
|
281
|
+
} catch (Exception ex) {
|
|
282
|
+
call.reject("Failed to delete contact.", null, ex);
|
|
283
|
+
}
|
|
215
284
|
}
|
|
216
285
|
|
|
286
|
+
// MARK: - Group operations
|
|
287
|
+
|
|
217
288
|
@PluginMethod
|
|
218
|
-
public void
|
|
219
|
-
|
|
289
|
+
public void getGroups(PluginCall call) {
|
|
290
|
+
if (!hasReadPermission()) {
|
|
291
|
+
call.reject("READ_CONTACTS permission not granted.");
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
ContentResolver resolver = getContext().getContentResolver();
|
|
296
|
+
JSArray groups = new JSArray();
|
|
297
|
+
|
|
298
|
+
try (
|
|
299
|
+
Cursor cursor = resolver.query(
|
|
300
|
+
ContactsContract.Groups.CONTENT_URI,
|
|
301
|
+
new String[] { ContactsContract.Groups._ID, ContactsContract.Groups.TITLE },
|
|
302
|
+
null,
|
|
303
|
+
null,
|
|
304
|
+
ContactsContract.Groups.TITLE + " ASC"
|
|
305
|
+
)
|
|
306
|
+
) {
|
|
307
|
+
if (cursor != null) {
|
|
308
|
+
while (cursor.moveToNext()) {
|
|
309
|
+
String id = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Groups._ID));
|
|
310
|
+
String name = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Groups.TITLE));
|
|
311
|
+
JSObject group = new JSObject();
|
|
312
|
+
group.put("id", id);
|
|
313
|
+
group.put("name", name);
|
|
314
|
+
groups.put(group);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
call.resolve(new JSObject().put("groups", groups));
|
|
318
|
+
} catch (Exception ex) {
|
|
319
|
+
call.reject("Failed to fetch groups.", null, ex);
|
|
320
|
+
}
|
|
220
321
|
}
|
|
221
322
|
|
|
222
323
|
@PluginMethod
|
|
223
|
-
public void
|
|
224
|
-
|
|
324
|
+
public void getGroupById(PluginCall call) {
|
|
325
|
+
if (!hasReadPermission()) {
|
|
326
|
+
call.reject("READ_CONTACTS permission not granted.");
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
JSObject options = call.getObject("options", new JSObject());
|
|
331
|
+
String groupId = options.getString("id");
|
|
332
|
+
|
|
333
|
+
if (groupId == null) {
|
|
334
|
+
call.reject("Missing group identifier.");
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
ContentResolver resolver = getContext().getContentResolver();
|
|
339
|
+
|
|
340
|
+
try (
|
|
341
|
+
Cursor cursor = resolver.query(
|
|
342
|
+
ContactsContract.Groups.CONTENT_URI,
|
|
343
|
+
new String[] { ContactsContract.Groups._ID, ContactsContract.Groups.TITLE },
|
|
344
|
+
ContactsContract.Groups._ID + " = ?",
|
|
345
|
+
new String[] { groupId },
|
|
346
|
+
null
|
|
347
|
+
)
|
|
348
|
+
) {
|
|
349
|
+
if (cursor != null && cursor.moveToFirst()) {
|
|
350
|
+
String id = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Groups._ID));
|
|
351
|
+
String name = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Groups.TITLE));
|
|
352
|
+
JSObject group = new JSObject();
|
|
353
|
+
group.put("id", id);
|
|
354
|
+
group.put("name", name);
|
|
355
|
+
call.resolve(new JSObject().put("group", group));
|
|
356
|
+
} else {
|
|
357
|
+
call.resolve(new JSObject().put("group", null));
|
|
358
|
+
}
|
|
359
|
+
} catch (Exception ex) {
|
|
360
|
+
call.reject("Failed to fetch group.", null, ex);
|
|
361
|
+
}
|
|
225
362
|
}
|
|
226
363
|
|
|
227
364
|
@PluginMethod
|
|
228
|
-
public void
|
|
229
|
-
|
|
365
|
+
public void createGroup(PluginCall call) {
|
|
366
|
+
if (!hasWritePermission()) {
|
|
367
|
+
call.reject("WRITE_CONTACTS permission not granted.");
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
JSObject options = call.getObject("options", new JSObject());
|
|
372
|
+
JSObject groupData = options.getJSObject("group");
|
|
373
|
+
|
|
374
|
+
if (groupData == null) {
|
|
375
|
+
call.reject("Missing group data.");
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
String name = groupData.getString("name");
|
|
380
|
+
if (name == null) {
|
|
381
|
+
call.reject("Missing group name.");
|
|
382
|
+
return;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
try {
|
|
386
|
+
ContentResolver resolver = getContext().getContentResolver();
|
|
387
|
+
ArrayList<android.content.ContentProviderOperation> ops = new ArrayList<>();
|
|
388
|
+
|
|
389
|
+
ops.add(
|
|
390
|
+
android.content.ContentProviderOperation.newInsert(ContactsContract.Groups.CONTENT_URI)
|
|
391
|
+
.withValue(ContactsContract.Groups.TITLE, name)
|
|
392
|
+
.build()
|
|
393
|
+
);
|
|
394
|
+
|
|
395
|
+
android.content.ContentProviderResult[] results = resolver.applyBatch(ContactsContract.AUTHORITY, ops);
|
|
396
|
+
if (results.length > 0 && results[0].uri != null) {
|
|
397
|
+
String groupId = results[0].uri.getLastPathSegment();
|
|
398
|
+
call.resolve(new JSObject().put("id", groupId));
|
|
399
|
+
} else {
|
|
400
|
+
call.reject("Failed to create group.");
|
|
401
|
+
}
|
|
402
|
+
} catch (Exception ex) {
|
|
403
|
+
call.reject("Failed to create group.", null, ex);
|
|
404
|
+
}
|
|
230
405
|
}
|
|
231
406
|
|
|
232
407
|
@PluginMethod
|
|
233
|
-
public void
|
|
234
|
-
|
|
408
|
+
public void deleteGroupById(PluginCall call) {
|
|
409
|
+
if (!hasWritePermission()) {
|
|
410
|
+
call.reject("WRITE_CONTACTS permission not granted.");
|
|
411
|
+
return;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
JSObject options = call.getObject("options", new JSObject());
|
|
415
|
+
String groupId = options.getString("id");
|
|
416
|
+
|
|
417
|
+
if (groupId == null) {
|
|
418
|
+
call.reject("Missing group identifier.");
|
|
419
|
+
return;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
try {
|
|
423
|
+
ContentResolver resolver = getContext().getContentResolver();
|
|
424
|
+
int rowsDeleted = resolver.delete(
|
|
425
|
+
ContactsContract.Groups.CONTENT_URI,
|
|
426
|
+
ContactsContract.Groups._ID + " = ?",
|
|
427
|
+
new String[] { groupId }
|
|
428
|
+
);
|
|
429
|
+
|
|
430
|
+
if (rowsDeleted > 0) {
|
|
431
|
+
call.resolve();
|
|
432
|
+
} else {
|
|
433
|
+
call.reject("Group not found or could not be deleted.");
|
|
434
|
+
}
|
|
435
|
+
} catch (Exception ex) {
|
|
436
|
+
call.reject("Failed to delete group.", null, ex);
|
|
437
|
+
}
|
|
235
438
|
}
|
|
236
439
|
|
|
440
|
+
// MARK: - UI picker and display operations
|
|
441
|
+
|
|
442
|
+
private static final int PICK_CONTACT_REQUEST = 7001;
|
|
443
|
+
private static final int VIEW_CONTACT_REQUEST = 7002;
|
|
444
|
+
private static final int CREATE_CONTACT_REQUEST = 7003;
|
|
445
|
+
private static final int EDIT_CONTACT_REQUEST = 7004;
|
|
446
|
+
|
|
447
|
+
private PluginCall currentPickerCall;
|
|
448
|
+
|
|
237
449
|
@PluginMethod
|
|
238
|
-
public void
|
|
239
|
-
|
|
450
|
+
public void pickContact(PluginCall call) {
|
|
451
|
+
currentPickerCall = call;
|
|
452
|
+
Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
|
|
453
|
+
startActivityForResult(call, intent, PICK_CONTACT_REQUEST);
|
|
240
454
|
}
|
|
241
455
|
|
|
242
456
|
@PluginMethod
|
|
243
|
-
public void
|
|
244
|
-
|
|
457
|
+
public void pickContacts(PluginCall call) {
|
|
458
|
+
// Android doesn't have a native multi-select contact picker
|
|
459
|
+
// Fall back to single selection
|
|
460
|
+
pickContact(call);
|
|
245
461
|
}
|
|
246
462
|
|
|
247
463
|
@PluginMethod
|
|
248
|
-
public void
|
|
249
|
-
|
|
464
|
+
public void displayContactById(PluginCall call) {
|
|
465
|
+
JSObject options = call.getObject("options", new JSObject());
|
|
466
|
+
String contactId = options.getString("id");
|
|
467
|
+
|
|
468
|
+
if (contactId == null) {
|
|
469
|
+
call.reject("Missing contact identifier.");
|
|
470
|
+
return;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
try {
|
|
474
|
+
Uri contactUri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, Long.parseLong(contactId));
|
|
475
|
+
Intent intent = new Intent(Intent.ACTION_VIEW, contactUri);
|
|
476
|
+
getContext().startActivity(intent);
|
|
477
|
+
call.resolve();
|
|
478
|
+
} catch (Exception ex) {
|
|
479
|
+
call.reject("Failed to display contact.", null, ex);
|
|
480
|
+
}
|
|
250
481
|
}
|
|
251
482
|
|
|
252
483
|
@PluginMethod
|
|
253
|
-
public void
|
|
254
|
-
|
|
484
|
+
public void displayCreateContact(PluginCall call) {
|
|
485
|
+
currentPickerCall = call;
|
|
486
|
+
Intent intent = new Intent(Intent.ACTION_INSERT, ContactsContract.Contacts.CONTENT_URI);
|
|
487
|
+
|
|
488
|
+
JSObject options = call.getObject("options", new JSObject());
|
|
489
|
+
if (options != null) {
|
|
490
|
+
JSObject contactData = options.getJSObject("contact");
|
|
491
|
+
if (contactData != null) {
|
|
492
|
+
populateIntent(intent, contactData);
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
startActivityForResult(call, intent, CREATE_CONTACT_REQUEST);
|
|
255
497
|
}
|
|
256
498
|
|
|
257
499
|
@PluginMethod
|
|
258
|
-
public void
|
|
259
|
-
|
|
500
|
+
public void displayUpdateContactById(PluginCall call) {
|
|
501
|
+
JSObject options = call.getObject("options", new JSObject());
|
|
502
|
+
String contactId = options.getString("id");
|
|
503
|
+
|
|
504
|
+
if (contactId == null) {
|
|
505
|
+
call.reject("Missing contact identifier.");
|
|
506
|
+
return;
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
try {
|
|
510
|
+
Uri contactUri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, Long.parseLong(contactId));
|
|
511
|
+
Intent intent = new Intent(Intent.ACTION_EDIT, contactUri);
|
|
512
|
+
intent.setType(ContactsContract.Contacts.CONTENT_ITEM_TYPE);
|
|
513
|
+
getContext().startActivity(intent);
|
|
514
|
+
call.resolve();
|
|
515
|
+
} catch (Exception ex) {
|
|
516
|
+
call.reject("Failed to display contact for editing.", null, ex);
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
@Override
|
|
521
|
+
protected void handleOnActivityResult(int requestCode, int resultCode, Intent data) {
|
|
522
|
+
super.handleOnActivityResult(requestCode, resultCode, data);
|
|
523
|
+
|
|
524
|
+
if (currentPickerCall == null) {
|
|
525
|
+
return;
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
PluginCall call = currentPickerCall;
|
|
529
|
+
currentPickerCall = null;
|
|
530
|
+
|
|
531
|
+
if (resultCode != android.app.Activity.RESULT_OK) {
|
|
532
|
+
if (requestCode == PICK_CONTACT_REQUEST) {
|
|
533
|
+
call.resolve(new JSObject().put("contacts", new JSArray()));
|
|
534
|
+
} else if (requestCode == CREATE_CONTACT_REQUEST) {
|
|
535
|
+
call.resolve(new JSObject());
|
|
536
|
+
}
|
|
537
|
+
return;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
try {
|
|
541
|
+
if (requestCode == PICK_CONTACT_REQUEST) {
|
|
542
|
+
if (data != null && data.getData() != null) {
|
|
543
|
+
String contactId = getContactIdFromUri(data.getData());
|
|
544
|
+
if (contactId != null) {
|
|
545
|
+
ContactBuilder builder = fetchContact(contactId);
|
|
546
|
+
if (builder != null) {
|
|
547
|
+
JSArray contacts = new JSArray();
|
|
548
|
+
contacts.put(builder.toJSObject());
|
|
549
|
+
call.resolve(new JSObject().put("contacts", contacts));
|
|
550
|
+
} else {
|
|
551
|
+
call.resolve(new JSObject().put("contacts", new JSArray()));
|
|
552
|
+
}
|
|
553
|
+
} else {
|
|
554
|
+
call.resolve(new JSObject().put("contacts", new JSArray()));
|
|
555
|
+
}
|
|
556
|
+
} else {
|
|
557
|
+
call.resolve(new JSObject().put("contacts", new JSArray()));
|
|
558
|
+
}
|
|
559
|
+
} else if (requestCode == CREATE_CONTACT_REQUEST) {
|
|
560
|
+
if (data != null && data.getData() != null) {
|
|
561
|
+
String contactId = getContactIdFromUri(data.getData());
|
|
562
|
+
if (contactId != null) {
|
|
563
|
+
call.resolve(new JSObject().put("id", contactId));
|
|
564
|
+
} else {
|
|
565
|
+
call.resolve(new JSObject());
|
|
566
|
+
}
|
|
567
|
+
} else {
|
|
568
|
+
call.resolve(new JSObject());
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
} catch (Exception ex) {
|
|
572
|
+
call.reject("Failed to process contact picker result.", null, ex);
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
private String getContactIdFromUri(Uri contactUri) {
|
|
577
|
+
ContentResolver resolver = getContext().getContentResolver();
|
|
578
|
+
try (Cursor cursor = resolver.query(contactUri, new String[] { ContactsContract.Contacts._ID }, null, null, null)) {
|
|
579
|
+
if (cursor != null && cursor.moveToFirst()) {
|
|
580
|
+
return cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts._ID));
|
|
581
|
+
}
|
|
582
|
+
} catch (Exception ex) {
|
|
583
|
+
// Ignore
|
|
584
|
+
}
|
|
585
|
+
return null;
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
// MARK: - Contact write helpers
|
|
589
|
+
|
|
590
|
+
private String insertContact(JSObject contactData) throws Exception {
|
|
591
|
+
ContentResolver resolver = getContext().getContentResolver();
|
|
592
|
+
ArrayList<android.content.ContentProviderOperation> ops = new ArrayList<>();
|
|
593
|
+
|
|
594
|
+
int rawContactInsertIndex = ops.size();
|
|
595
|
+
ops.add(
|
|
596
|
+
android.content.ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
|
|
597
|
+
.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, (String) null)
|
|
598
|
+
.withValue(ContactsContract.RawContacts.ACCOUNT_NAME, (String) null)
|
|
599
|
+
.build()
|
|
600
|
+
);
|
|
601
|
+
|
|
602
|
+
// Add structured name
|
|
603
|
+
if (
|
|
604
|
+
contactData.has("givenName") ||
|
|
605
|
+
contactData.has("familyName") ||
|
|
606
|
+
contactData.has("middleName") ||
|
|
607
|
+
contactData.has("namePrefix") ||
|
|
608
|
+
contactData.has("nameSuffix")
|
|
609
|
+
) {
|
|
610
|
+
ops.add(
|
|
611
|
+
android.content.ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
|
|
612
|
+
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, rawContactInsertIndex)
|
|
613
|
+
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
|
|
614
|
+
.withValue(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, contactData.getString("givenName"))
|
|
615
|
+
.withValue(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME, contactData.getString("familyName"))
|
|
616
|
+
.withValue(ContactsContract.CommonDataKinds.StructuredName.MIDDLE_NAME, contactData.getString("middleName"))
|
|
617
|
+
.withValue(ContactsContract.CommonDataKinds.StructuredName.PREFIX, contactData.getString("namePrefix"))
|
|
618
|
+
.withValue(ContactsContract.CommonDataKinds.StructuredName.SUFFIX, contactData.getString("nameSuffix"))
|
|
619
|
+
.build()
|
|
620
|
+
);
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
// Add organization
|
|
624
|
+
if (contactData.has("organizationName") || contactData.has("jobTitle")) {
|
|
625
|
+
ops.add(
|
|
626
|
+
android.content.ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
|
|
627
|
+
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, rawContactInsertIndex)
|
|
628
|
+
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE)
|
|
629
|
+
.withValue(ContactsContract.CommonDataKinds.Organization.COMPANY, contactData.getString("organizationName"))
|
|
630
|
+
.withValue(ContactsContract.CommonDataKinds.Organization.TITLE, contactData.getString("jobTitle"))
|
|
631
|
+
.build()
|
|
632
|
+
);
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
// Add note
|
|
636
|
+
if (contactData.has("note")) {
|
|
637
|
+
ops.add(
|
|
638
|
+
android.content.ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
|
|
639
|
+
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, rawContactInsertIndex)
|
|
640
|
+
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Note.CONTENT_ITEM_TYPE)
|
|
641
|
+
.withValue(ContactsContract.CommonDataKinds.Note.NOTE, contactData.getString("note"))
|
|
642
|
+
.build()
|
|
643
|
+
);
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
// Add email addresses
|
|
647
|
+
if (contactData.has("emailAddresses")) {
|
|
648
|
+
try {
|
|
649
|
+
org.json.JSONArray emails = contactData.getJSONArray("emailAddresses");
|
|
650
|
+
for (int i = 0; i < emails.length(); i++) {
|
|
651
|
+
org.json.JSONObject email = emails.getJSONObject(i);
|
|
652
|
+
String value = email.optString("value");
|
|
653
|
+
String type = email.optString("type", "OTHER");
|
|
654
|
+
String label = email.optString("label");
|
|
655
|
+
|
|
656
|
+
ops.add(
|
|
657
|
+
android.content.ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
|
|
658
|
+
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, rawContactInsertIndex)
|
|
659
|
+
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE)
|
|
660
|
+
.withValue(ContactsContract.CommonDataKinds.Email.ADDRESS, value)
|
|
661
|
+
.withValue(ContactsContract.CommonDataKinds.Email.TYPE, reverseMapEmailType(type))
|
|
662
|
+
.withValue(ContactsContract.CommonDataKinds.Email.LABEL, label)
|
|
663
|
+
.build()
|
|
664
|
+
);
|
|
665
|
+
}
|
|
666
|
+
} catch (Exception ex) {
|
|
667
|
+
// Ignore
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
// Add phone numbers
|
|
672
|
+
if (contactData.has("phoneNumbers")) {
|
|
673
|
+
try {
|
|
674
|
+
org.json.JSONArray phones = contactData.getJSONArray("phoneNumbers");
|
|
675
|
+
for (int i = 0; i < phones.length(); i++) {
|
|
676
|
+
org.json.JSONObject phone = phones.getJSONObject(i);
|
|
677
|
+
String value = phone.optString("value");
|
|
678
|
+
String type = phone.optString("type", "OTHER");
|
|
679
|
+
String label = phone.optString("label");
|
|
680
|
+
|
|
681
|
+
ops.add(
|
|
682
|
+
android.content.ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
|
|
683
|
+
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, rawContactInsertIndex)
|
|
684
|
+
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
|
|
685
|
+
.withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, value)
|
|
686
|
+
.withValue(ContactsContract.CommonDataKinds.Phone.TYPE, reverseMapPhoneType(type))
|
|
687
|
+
.withValue(ContactsContract.CommonDataKinds.Phone.LABEL, label)
|
|
688
|
+
.build()
|
|
689
|
+
);
|
|
690
|
+
}
|
|
691
|
+
} catch (Exception ex) {
|
|
692
|
+
// Ignore
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
// Add postal addresses
|
|
697
|
+
if (contactData.has("postalAddresses")) {
|
|
698
|
+
try {
|
|
699
|
+
org.json.JSONArray addresses = contactData.getJSONArray("postalAddresses");
|
|
700
|
+
for (int i = 0; i < addresses.length(); i++) {
|
|
701
|
+
org.json.JSONObject address = addresses.getJSONObject(i);
|
|
702
|
+
|
|
703
|
+
ops.add(
|
|
704
|
+
android.content.ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
|
|
705
|
+
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, rawContactInsertIndex)
|
|
706
|
+
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE)
|
|
707
|
+
.withValue(ContactsContract.CommonDataKinds.StructuredPostal.STREET, address.optString("street"))
|
|
708
|
+
.withValue(ContactsContract.CommonDataKinds.StructuredPostal.CITY, address.optString("city"))
|
|
709
|
+
.withValue(ContactsContract.CommonDataKinds.StructuredPostal.REGION, address.optString("state"))
|
|
710
|
+
.withValue(ContactsContract.CommonDataKinds.StructuredPostal.POSTCODE, address.optString("postalCode"))
|
|
711
|
+
.withValue(ContactsContract.CommonDataKinds.StructuredPostal.COUNTRY, address.optString("country"))
|
|
712
|
+
.withValue(
|
|
713
|
+
ContactsContract.CommonDataKinds.StructuredPostal.TYPE,
|
|
714
|
+
reverseMapPostalType(address.optString("type", "OTHER"))
|
|
715
|
+
)
|
|
716
|
+
.withValue(ContactsContract.CommonDataKinds.StructuredPostal.LABEL, address.optString("label"))
|
|
717
|
+
.build()
|
|
718
|
+
);
|
|
719
|
+
}
|
|
720
|
+
} catch (Exception ex) {
|
|
721
|
+
// Ignore
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
// Add URL addresses
|
|
726
|
+
if (contactData.has("urlAddresses")) {
|
|
727
|
+
try {
|
|
728
|
+
org.json.JSONArray urls = contactData.getJSONArray("urlAddresses");
|
|
729
|
+
for (int i = 0; i < urls.length(); i++) {
|
|
730
|
+
org.json.JSONObject url = urls.getJSONObject(i);
|
|
731
|
+
|
|
732
|
+
ops.add(
|
|
733
|
+
android.content.ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
|
|
734
|
+
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, rawContactInsertIndex)
|
|
735
|
+
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Website.CONTENT_ITEM_TYPE)
|
|
736
|
+
.withValue(ContactsContract.CommonDataKinds.Website.URL, url.optString("value"))
|
|
737
|
+
.withValue(ContactsContract.CommonDataKinds.Website.TYPE, reverseMapUrlType(url.optString("type", "OTHER")))
|
|
738
|
+
.withValue(ContactsContract.CommonDataKinds.Website.LABEL, url.optString("label"))
|
|
739
|
+
.build()
|
|
740
|
+
);
|
|
741
|
+
}
|
|
742
|
+
} catch (Exception ex) {
|
|
743
|
+
// Ignore
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
// Execute batch
|
|
748
|
+
android.content.ContentProviderResult[] results = resolver.applyBatch(ContactsContract.AUTHORITY, ops);
|
|
749
|
+
|
|
750
|
+
// Get the contact ID from the first result
|
|
751
|
+
if (results.length > 0 && results[0].uri != null) {
|
|
752
|
+
String rawContactId = results[0].uri.getLastPathSegment();
|
|
753
|
+
// Query for the actual contact ID
|
|
754
|
+
try (
|
|
755
|
+
Cursor cursor = resolver.query(
|
|
756
|
+
ContactsContract.RawContacts.CONTENT_URI,
|
|
757
|
+
new String[] { ContactsContract.RawContacts.CONTACT_ID },
|
|
758
|
+
ContactsContract.RawContacts._ID + " = ?",
|
|
759
|
+
new String[] { rawContactId },
|
|
760
|
+
null
|
|
761
|
+
)
|
|
762
|
+
) {
|
|
763
|
+
if (cursor != null && cursor.moveToFirst()) {
|
|
764
|
+
return cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.RawContacts.CONTACT_ID));
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
throw new Exception("Failed to create contact");
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
@SuppressLint("Range")
|
|
773
|
+
private void updateContact(String contactId, JSObject contactData) throws Exception {
|
|
774
|
+
ContentResolver resolver = getContext().getContentResolver();
|
|
775
|
+
ArrayList<android.content.ContentProviderOperation> ops = new ArrayList<>();
|
|
776
|
+
|
|
777
|
+
// Find the raw contact ID for this contact
|
|
778
|
+
String rawContactId = null;
|
|
779
|
+
try (
|
|
780
|
+
Cursor cursor = resolver.query(
|
|
781
|
+
ContactsContract.RawContacts.CONTENT_URI,
|
|
782
|
+
new String[] { ContactsContract.RawContacts._ID },
|
|
783
|
+
ContactsContract.RawContacts.CONTACT_ID + " = ?",
|
|
784
|
+
new String[] { contactId },
|
|
785
|
+
null
|
|
786
|
+
)
|
|
787
|
+
) {
|
|
788
|
+
if (cursor != null && cursor.moveToFirst()) {
|
|
789
|
+
rawContactId = cursor.getString(cursor.getColumnIndex(ContactsContract.RawContacts._ID));
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
if (rawContactId == null) {
|
|
794
|
+
throw new Exception("Contact not found");
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
// Delete existing data
|
|
798
|
+
ops.add(
|
|
799
|
+
android.content.ContentProviderOperation.newDelete(ContactsContract.Data.CONTENT_URI)
|
|
800
|
+
.withSelection(ContactsContract.Data.RAW_CONTACT_ID + " = ?", new String[] { rawContactId })
|
|
801
|
+
.build()
|
|
802
|
+
);
|
|
803
|
+
|
|
804
|
+
// Re-insert all data (simpler than updating individual fields)
|
|
805
|
+
int rawContactIdValue = Integer.parseInt(rawContactId);
|
|
806
|
+
|
|
807
|
+
// Add structured name
|
|
808
|
+
if (
|
|
809
|
+
contactData.has("givenName") ||
|
|
810
|
+
contactData.has("familyName") ||
|
|
811
|
+
contactData.has("middleName") ||
|
|
812
|
+
contactData.has("namePrefix") ||
|
|
813
|
+
contactData.has("nameSuffix")
|
|
814
|
+
) {
|
|
815
|
+
ops.add(
|
|
816
|
+
android.content.ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
|
|
817
|
+
.withValue(ContactsContract.Data.RAW_CONTACT_ID, rawContactIdValue)
|
|
818
|
+
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
|
|
819
|
+
.withValue(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, contactData.getString("givenName"))
|
|
820
|
+
.withValue(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME, contactData.getString("familyName"))
|
|
821
|
+
.withValue(ContactsContract.CommonDataKinds.StructuredName.MIDDLE_NAME, contactData.getString("middleName"))
|
|
822
|
+
.withValue(ContactsContract.CommonDataKinds.StructuredName.PREFIX, contactData.getString("namePrefix"))
|
|
823
|
+
.withValue(ContactsContract.CommonDataKinds.StructuredName.SUFFIX, contactData.getString("nameSuffix"))
|
|
824
|
+
.build()
|
|
825
|
+
);
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
// Similar logic for other fields (organization, note, emails, phones, etc.)
|
|
829
|
+
// Add organization
|
|
830
|
+
if (contactData.has("organizationName") || contactData.has("jobTitle")) {
|
|
831
|
+
ops.add(
|
|
832
|
+
android.content.ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
|
|
833
|
+
.withValue(ContactsContract.Data.RAW_CONTACT_ID, rawContactIdValue)
|
|
834
|
+
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE)
|
|
835
|
+
.withValue(ContactsContract.CommonDataKinds.Organization.COMPANY, contactData.getString("organizationName"))
|
|
836
|
+
.withValue(ContactsContract.CommonDataKinds.Organization.TITLE, contactData.getString("jobTitle"))
|
|
837
|
+
.build()
|
|
838
|
+
);
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
// Add note
|
|
842
|
+
if (contactData.has("note")) {
|
|
843
|
+
ops.add(
|
|
844
|
+
android.content.ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
|
|
845
|
+
.withValue(ContactsContract.Data.RAW_CONTACT_ID, rawContactIdValue)
|
|
846
|
+
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Note.CONTENT_ITEM_TYPE)
|
|
847
|
+
.withValue(ContactsContract.CommonDataKinds.Note.NOTE, contactData.getString("note"))
|
|
848
|
+
.build()
|
|
849
|
+
);
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
// Add emails, phones, addresses, URLs (same logic as insert)
|
|
853
|
+
if (contactData.has("emailAddresses")) {
|
|
854
|
+
try {
|
|
855
|
+
org.json.JSONArray emails = contactData.getJSONArray("emailAddresses");
|
|
856
|
+
for (int i = 0; i < emails.length(); i++) {
|
|
857
|
+
org.json.JSONObject email = emails.getJSONObject(i);
|
|
858
|
+
ops.add(
|
|
859
|
+
android.content.ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
|
|
860
|
+
.withValue(ContactsContract.Data.RAW_CONTACT_ID, rawContactIdValue)
|
|
861
|
+
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE)
|
|
862
|
+
.withValue(ContactsContract.CommonDataKinds.Email.ADDRESS, email.optString("value"))
|
|
863
|
+
.withValue(ContactsContract.CommonDataKinds.Email.TYPE, reverseMapEmailType(email.optString("type", "OTHER")))
|
|
864
|
+
.withValue(ContactsContract.CommonDataKinds.Email.LABEL, email.optString("label"))
|
|
865
|
+
.build()
|
|
866
|
+
);
|
|
867
|
+
}
|
|
868
|
+
} catch (Exception ex) {
|
|
869
|
+
// Ignore
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
if (contactData.has("phoneNumbers")) {
|
|
874
|
+
try {
|
|
875
|
+
org.json.JSONArray phones = contactData.getJSONArray("phoneNumbers");
|
|
876
|
+
for (int i = 0; i < phones.length(); i++) {
|
|
877
|
+
org.json.JSONObject phone = phones.getJSONObject(i);
|
|
878
|
+
ops.add(
|
|
879
|
+
android.content.ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
|
|
880
|
+
.withValue(ContactsContract.Data.RAW_CONTACT_ID, rawContactIdValue)
|
|
881
|
+
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
|
|
882
|
+
.withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, phone.optString("value"))
|
|
883
|
+
.withValue(ContactsContract.CommonDataKinds.Phone.TYPE, reverseMapPhoneType(phone.optString("type", "OTHER")))
|
|
884
|
+
.withValue(ContactsContract.CommonDataKinds.Phone.LABEL, phone.optString("label"))
|
|
885
|
+
.build()
|
|
886
|
+
);
|
|
887
|
+
}
|
|
888
|
+
} catch (Exception ex) {
|
|
889
|
+
// Ignore
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
resolver.applyBatch(ContactsContract.AUTHORITY, ops);
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
private void populateIntent(Intent intent, JSObject contactData) {
|
|
897
|
+
// Build full name from components
|
|
898
|
+
StringBuilder nameBuilder = new StringBuilder();
|
|
899
|
+
if (contactData.has("givenName")) {
|
|
900
|
+
nameBuilder.append(contactData.getString("givenName"));
|
|
901
|
+
}
|
|
902
|
+
if (contactData.has("familyName")) {
|
|
903
|
+
if (nameBuilder.length() > 0) {
|
|
904
|
+
nameBuilder.append(" ");
|
|
905
|
+
}
|
|
906
|
+
nameBuilder.append(contactData.getString("familyName"));
|
|
907
|
+
}
|
|
908
|
+
if (nameBuilder.length() > 0) {
|
|
909
|
+
intent.putExtra(ContactsContract.Intents.Insert.NAME, nameBuilder.toString());
|
|
910
|
+
}
|
|
911
|
+
|
|
912
|
+
if (contactData.has("organizationName")) {
|
|
913
|
+
intent.putExtra(ContactsContract.Intents.Insert.COMPANY, contactData.getString("organizationName"));
|
|
914
|
+
}
|
|
915
|
+
if (contactData.has("jobTitle")) {
|
|
916
|
+
intent.putExtra(ContactsContract.Intents.Insert.JOB_TITLE, contactData.getString("jobTitle"));
|
|
917
|
+
}
|
|
918
|
+
if (contactData.has("note")) {
|
|
919
|
+
intent.putExtra(ContactsContract.Intents.Insert.NOTES, contactData.getString("note"));
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
// Add first email if available
|
|
923
|
+
if (contactData.has("emailAddresses")) {
|
|
924
|
+
try {
|
|
925
|
+
org.json.JSONArray emails = contactData.getJSONArray("emailAddresses");
|
|
926
|
+
if (emails.length() > 0) {
|
|
927
|
+
org.json.JSONObject email = emails.getJSONObject(0);
|
|
928
|
+
intent.putExtra(ContactsContract.Intents.Insert.EMAIL, email.optString("value"));
|
|
929
|
+
}
|
|
930
|
+
} catch (Exception ex) {
|
|
931
|
+
// Ignore
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
// Add first phone if available
|
|
936
|
+
if (contactData.has("phoneNumbers")) {
|
|
937
|
+
try {
|
|
938
|
+
org.json.JSONArray phones = contactData.getJSONArray("phoneNumbers");
|
|
939
|
+
if (phones.length() > 0) {
|
|
940
|
+
org.json.JSONObject phone = phones.getJSONObject(0);
|
|
941
|
+
intent.putExtra(ContactsContract.Intents.Insert.PHONE, phone.optString("value"));
|
|
942
|
+
}
|
|
943
|
+
} catch (Exception ex) {
|
|
944
|
+
// Ignore
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
private int reverseMapEmailType(String type) {
|
|
950
|
+
switch (type) {
|
|
951
|
+
case "HOME":
|
|
952
|
+
return ContactsContract.CommonDataKinds.Email.TYPE_HOME;
|
|
953
|
+
case "WORK":
|
|
954
|
+
return ContactsContract.CommonDataKinds.Email.TYPE_WORK;
|
|
955
|
+
case "MOBILE":
|
|
956
|
+
return ContactsContract.CommonDataKinds.Email.TYPE_MOBILE;
|
|
957
|
+
case "CUSTOM":
|
|
958
|
+
return ContactsContract.CommonDataKinds.Email.TYPE_CUSTOM;
|
|
959
|
+
default:
|
|
960
|
+
return ContactsContract.CommonDataKinds.Email.TYPE_OTHER;
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
private int reverseMapPhoneType(String type) {
|
|
965
|
+
switch (type) {
|
|
966
|
+
case "HOME":
|
|
967
|
+
return ContactsContract.CommonDataKinds.Phone.TYPE_HOME;
|
|
968
|
+
case "WORK":
|
|
969
|
+
return ContactsContract.CommonDataKinds.Phone.TYPE_WORK;
|
|
970
|
+
case "MOBILE":
|
|
971
|
+
return ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE;
|
|
972
|
+
case "MAIN":
|
|
973
|
+
return ContactsContract.CommonDataKinds.Phone.TYPE_MAIN;
|
|
974
|
+
case "HOME_FAX":
|
|
975
|
+
return ContactsContract.CommonDataKinds.Phone.TYPE_FAX_HOME;
|
|
976
|
+
case "WORK_FAX":
|
|
977
|
+
return ContactsContract.CommonDataKinds.Phone.TYPE_FAX_WORK;
|
|
978
|
+
case "OTHER_FAX":
|
|
979
|
+
return ContactsContract.CommonDataKinds.Phone.TYPE_OTHER_FAX;
|
|
980
|
+
case "PAGER":
|
|
981
|
+
return ContactsContract.CommonDataKinds.Phone.TYPE_PAGER;
|
|
982
|
+
case "CAR":
|
|
983
|
+
return ContactsContract.CommonDataKinds.Phone.TYPE_CAR;
|
|
984
|
+
case "CALLBACK":
|
|
985
|
+
return ContactsContract.CommonDataKinds.Phone.TYPE_CALLBACK;
|
|
986
|
+
case "COMPANY_MAIN":
|
|
987
|
+
return ContactsContract.CommonDataKinds.Phone.TYPE_COMPANY_MAIN;
|
|
988
|
+
case "ASSISTANT":
|
|
989
|
+
return ContactsContract.CommonDataKinds.Phone.TYPE_ASSISTANT;
|
|
990
|
+
case "CUSTOM":
|
|
991
|
+
return ContactsContract.CommonDataKinds.Phone.TYPE_CUSTOM;
|
|
992
|
+
default:
|
|
993
|
+
return ContactsContract.CommonDataKinds.Phone.TYPE_OTHER;
|
|
994
|
+
}
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
private int reverseMapPostalType(String type) {
|
|
998
|
+
switch (type) {
|
|
999
|
+
case "HOME":
|
|
1000
|
+
return ContactsContract.CommonDataKinds.StructuredPostal.TYPE_HOME;
|
|
1001
|
+
case "WORK":
|
|
1002
|
+
return ContactsContract.CommonDataKinds.StructuredPostal.TYPE_WORK;
|
|
1003
|
+
case "CUSTOM":
|
|
1004
|
+
return ContactsContract.CommonDataKinds.StructuredPostal.TYPE_CUSTOM;
|
|
1005
|
+
default:
|
|
1006
|
+
return ContactsContract.CommonDataKinds.StructuredPostal.TYPE_OTHER;
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
|
|
1010
|
+
private int reverseMapUrlType(String type) {
|
|
1011
|
+
switch (type) {
|
|
1012
|
+
case "HOME":
|
|
1013
|
+
return ContactsContract.CommonDataKinds.Website.TYPE_HOME;
|
|
1014
|
+
case "WORK":
|
|
1015
|
+
return ContactsContract.CommonDataKinds.Website.TYPE_WORK;
|
|
1016
|
+
case "BLOG":
|
|
1017
|
+
return ContactsContract.CommonDataKinds.Website.TYPE_BLOG;
|
|
1018
|
+
case "PROFILE":
|
|
1019
|
+
return ContactsContract.CommonDataKinds.Website.TYPE_PROFILE;
|
|
1020
|
+
case "FTP":
|
|
1021
|
+
return ContactsContract.CommonDataKinds.Website.TYPE_FTP;
|
|
1022
|
+
case "CUSTOM":
|
|
1023
|
+
return ContactsContract.CommonDataKinds.Website.TYPE_CUSTOM;
|
|
1024
|
+
default:
|
|
1025
|
+
return ContactsContract.CommonDataKinds.Website.TYPE_OTHER;
|
|
1026
|
+
}
|
|
260
1027
|
}
|
|
261
1028
|
|
|
262
1029
|
// MARK: - Permissions helpers
|
|
@@ -265,6 +1032,10 @@ public class CapacitorContactsPlugin extends Plugin {
|
|
|
265
1032
|
return getPermissionState("readContacts") == PermissionState.GRANTED;
|
|
266
1033
|
}
|
|
267
1034
|
|
|
1035
|
+
private boolean hasWritePermission() {
|
|
1036
|
+
return getPermissionState("writeContacts") == PermissionState.GRANTED;
|
|
1037
|
+
}
|
|
1038
|
+
|
|
268
1039
|
private JSObject buildPermissionStatus() {
|
|
269
1040
|
JSObject status = new JSObject();
|
|
270
1041
|
status.put("readContacts", mapPermissionState(getPermissionState("readContacts")));
|