@aalzehla/capacitor-contacts 0.0.5 → 8.0.0
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/{AalzehlaCapacitorContacts.podspec → CapacitorCommunityContacts.podspec} +3 -3
- package/README.md +69 -45
- package/android/build.gradle +15 -12
- package/android/src/main/java/getcapacitor/community/contacts/BiMap.java +45 -0
- package/android/src/main/java/getcapacitor/community/contacts/ContactPayload.java +286 -0
- package/android/src/main/java/getcapacitor/community/contacts/Contacts.java +384 -0
- package/android/src/main/java/getcapacitor/community/contacts/ContactsPlugin.java +255 -0
- package/android/src/main/java/getcapacitor/community/contacts/CreateContactInput.java +233 -0
- package/android/src/main/java/getcapacitor/community/contacts/GetContactsProjectionInput.java +214 -0
- package/dist/esm/definitions.d.ts +285 -19
- package/dist/esm/definitions.js +47 -1
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/index.d.ts +3 -3
- package/dist/esm/index.js +3 -3
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/web.d.ts +9 -7
- package/dist/esm/web.js +21 -7
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +73 -14
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +74 -15
- package/dist/plugin.js.map +1 -1
- package/ios/Plugin/BiMap.swift +42 -0
- package/ios/Plugin/ContactPayload.swift +227 -0
- package/ios/Plugin/Contacts.swift +227 -0
- package/ios/Plugin/ContactsPlugin.h +10 -0
- package/ios/Plugin/ContactsPlugin.m +14 -0
- package/ios/Plugin/ContactsPlugin.swift +221 -0
- package/ios/Plugin/CreateContactInput.swift +187 -0
- package/ios/Plugin/GetContactsProjectionInput.swift +119 -0
- package/ios/Plugin/Info.plist +24 -0
- package/package.json +33 -30
- package/Package.swift +0 -28
- package/android/src/main/java/com/aalzehla/capacitor/contacts/CapacitorContactsPlugin.java +0 -177
- package/android/src/main/java/com/aalzehla/capacitor/contacts/ContactDataExtractorVisitor.java +0 -122
- package/android/src/main/java/com/aalzehla/capacitor/contacts/ContactExtractorVisitor.java +0 -31
- package/android/src/main/java/com/aalzehla/capacitor/contacts/PluginContactFields.java +0 -17
- package/android/src/main/java/com/aalzehla/capacitor/contacts/contentQuery/ContentQuery.java +0 -83
- package/android/src/main/java/com/aalzehla/capacitor/contacts/contentQuery/ContentQueryService.java +0 -60
- package/android/src/main/java/com/aalzehla/capacitor/contacts/utils/Utils.java +0 -19
- package/android/src/main/java/com/aalzehla/capacitor/contacts/utils/Visitable.java +0 -5
- package/android/src/main/java/com/aalzehla/capacitor/contacts/utils/Visitor.java +0 -5
- package/dist/docs.json +0 -145
- package/ios/Sources/CapacitorContactsPlugin/CapacitorContactsPlugin.swift +0 -168
- package/ios/Tests/CapacitorContactsPluginTests/CapacitorContactsPluginTests.swift +0 -15
|
@@ -3,15 +3,15 @@ require 'json'
|
|
|
3
3
|
package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
|
|
4
4
|
|
|
5
5
|
Pod::Spec.new do |s|
|
|
6
|
-
s.name = '
|
|
6
|
+
s.name = 'CapacitorCommunityContacts'
|
|
7
7
|
s.version = package['version']
|
|
8
8
|
s.summary = package['description']
|
|
9
9
|
s.license = package['license']
|
|
10
10
|
s.homepage = package['repository']['url']
|
|
11
11
|
s.author = package['author']
|
|
12
12
|
s.source = { :git => package['repository']['url'], :tag => s.version.to_s }
|
|
13
|
-
s.source_files = 'ios/
|
|
14
|
-
s.ios.deployment_target
|
|
13
|
+
s.source_files = 'ios/Plugin/**/*.{swift,h,m,c,cc,mm,cpp}'
|
|
14
|
+
s.ios.deployment_target = '15.0'
|
|
15
15
|
s.dependency 'Capacitor'
|
|
16
16
|
s.swift_version = '5.1'
|
|
17
17
|
end
|
package/README.md
CHANGED
|
@@ -1,67 +1,91 @@
|
|
|
1
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img
|
|
3
|
+
src="https://user-images.githubusercontent.com/236501/85893648-1c92e880-b7a8-11ea-926d-95355b8175c7.png"
|
|
4
|
+
width="128"
|
|
5
|
+
height="128"
|
|
6
|
+
/>
|
|
7
|
+
</p>
|
|
2
8
|
|
|
3
|
-
|
|
9
|
+
<h3 id="home" align="center">
|
|
10
|
+
Contacts
|
|
11
|
+
</h3>
|
|
4
12
|
|
|
5
|
-
|
|
13
|
+
<p align="center">
|
|
14
|
+
<strong>
|
|
15
|
+
<code>@capacitor-community/contacts</code>
|
|
16
|
+
</strong>
|
|
17
|
+
</p>
|
|
6
18
|
|
|
7
|
-
|
|
8
|
-
npm install @aalzehla/capacitor-contacts
|
|
9
|
-
npx cap sync
|
|
10
|
-
```
|
|
19
|
+
<p align="center">Capacitor Plugin for accessing Contacts.</p>
|
|
11
20
|
|
|
12
|
-
|
|
21
|
+
<p align="center">
|
|
22
|
+
<img src="https://img.shields.io/badge/supported%20capacitor%20versions-v3,%20v4,%20v5,%20v6%20and%20v7-blue?logo=Capacitor&style=flat-square" />
|
|
23
|
+
<img src="https://img.shields.io/maintenance/yes/2026?style=flat-square" />
|
|
24
|
+
<a href="https://www.npmjs.com/package/@capacitor-community/contacts">
|
|
25
|
+
<img src="https://img.shields.io/npm/l/@capacitor-community/contacts?style=flat-square" />
|
|
26
|
+
</a>
|
|
27
|
+
<br>
|
|
28
|
+
<a href="https://www.npmjs.com/package/@capacitor-community/contacts">
|
|
29
|
+
<img src="https://img.shields.io/npm/dw/@capacitor-community/contacts?style=flat-square" />
|
|
30
|
+
</a>
|
|
31
|
+
<a href="https://www.npmjs.com/package/@capacitor-community/contacts">
|
|
32
|
+
<img src="https://img.shields.io/npm/v/@capacitor-community/contacts?style=flat-square" />
|
|
33
|
+
</a>
|
|
34
|
+
</p>
|
|
13
35
|
|
|
14
|
-
|
|
36
|
+
## Purpose
|
|
15
37
|
|
|
16
|
-
|
|
17
|
-
* [`close()`](#close)
|
|
18
|
-
* [Interfaces](#interfaces)
|
|
38
|
+
This plugin enables you to access the native contacts APIs of iOS and Android. It allows you to retrieve, create and delete contacts.
|
|
19
39
|
|
|
20
|
-
|
|
40
|
+
## Versions
|
|
21
41
|
|
|
22
|
-
|
|
23
|
-
<!--Update the source file JSDoc comments and rerun docgen to update the docs below-->
|
|
42
|
+
Currently there are three actively maintained versions of this plugin. The API of these versions is identical. The only difference between these versions is the supported Capacitor versions.
|
|
24
43
|
|
|
25
|
-
|
|
44
|
+
| Plugin | Capacitor | Status | Documentation |
|
|
45
|
+
| ------ | --------- | ------ | ------------------------------------------------------- |
|
|
46
|
+
| v7.x | v7.x | LTS | [Link](https://capacitor-community.github.io/contacts/) |
|
|
47
|
+
| v6.x | v6.x | LTS | [Link](https://capacitor-community.github.io/contacts/) |
|
|
48
|
+
| v5.x | v5.x | LTS | [Link](https://capacitor-community.github.io/contacts/) |
|
|
49
|
+
| v4.x | v4.x | LTS | [Link](https://capacitor-community.github.io/contacts/) |
|
|
50
|
+
| v3.x | v3.x | LTS | [Link](https://capacitor-community.github.io/contacts/) |
|
|
26
51
|
|
|
27
|
-
|
|
28
|
-
open() => Promise<Contact[]>
|
|
29
|
-
```
|
|
52
|
+
If you are installing this plugin into a new project, you can ignore the following explanation.
|
|
30
53
|
|
|
31
|
-
|
|
54
|
+
In the past a few other versions of this plugin were released, also targeting different versions of Capacitor:
|
|
32
55
|
|
|
33
|
-
|
|
56
|
+
| Plugin | Capacitor | Status | Documentation |
|
|
57
|
+
| ------------- | --------- | ---------- | --------------------------------------------------------------------------------------------------------------- |
|
|
58
|
+
| v2.x | v4.x | Deprecated | [Link](https://github.com/capacitor-community/contacts/blob/v2.0.0/README.md) |
|
|
59
|
+
| v1.0.9 and up | v3.x | Deprecated | [Link](https://github.com/capacitor-community/contacts/blob/1.1.3/README.md) |
|
|
60
|
+
| v1.0.0 and up | v2.x | Deprecated | [Link](https://github.com/capacitor-community/contacts/blob/0cb99be68dc8ee4547c75f932872bd065f5509d2/README.md) |
|
|
61
|
+
| v0.x | v2.x | Deprecated | [Link](https://github.com/capacitor-community/contacts/blob/0.1.1/README.md) |
|
|
34
62
|
|
|
63
|
+
Admittedly, this wasn't the most consistent versioning strategy, and we'll keep it more coherent in the future.
|
|
35
64
|
|
|
36
|
-
|
|
65
|
+
It's highly recommended to upgrade to either v3, v4, v5, v6 or v7 if you are using an old version!
|
|
37
66
|
|
|
38
|
-
|
|
39
|
-
close() => Promise<void>
|
|
40
|
-
```
|
|
67
|
+
<p class="hide-next-element"></p>
|
|
41
68
|
|
|
42
|
-
|
|
69
|
+
## Documentation
|
|
43
70
|
|
|
71
|
+
<p class="hide-next-element"></p>
|
|
44
72
|
|
|
45
|
-
|
|
73
|
+
Extensive documentation is available [here](https://capacitor-community.github.io/contacts/).
|
|
46
74
|
|
|
75
|
+
<p class="hide-next-element"></p>
|
|
47
76
|
|
|
48
|
-
|
|
77
|
+
## Shortcuts
|
|
49
78
|
|
|
50
|
-
|
|
51
|
-
| ----------------------------- | ------------------- |
|
|
52
|
-
| **`identifier`** | <code>string</code> |
|
|
53
|
-
| **`androidContactLookupKey`** | <code>string</code> |
|
|
54
|
-
| **`contactId`** | <code>string</code> |
|
|
55
|
-
| **`givenName`** | <code>string</code> |
|
|
56
|
-
| **`familyName`** | <code>string</code> |
|
|
57
|
-
| **`nickname`** | <code>string</code> |
|
|
58
|
-
| **`fullName`** | <code>string</code> |
|
|
59
|
-
| **`jobTitle`** | <code>string</code> |
|
|
60
|
-
| **`departmentName`** | <code>string</code> |
|
|
61
|
-
| **`organizationName`** | <code>string</code> |
|
|
62
|
-
| **`note`** | <code>string</code> |
|
|
63
|
-
| **`phoneNumbers`** | <code>any[]</code> |
|
|
64
|
-
| **`emailAddresses`** | <code>any[]</code> |
|
|
65
|
-
| **`postalAddresses`** | <code>any[]</code> |
|
|
79
|
+
<p class="hide-next-element"></p>
|
|
66
80
|
|
|
67
|
-
|
|
81
|
+
- [Documentation homepage](https://capacitor-community.github.io/contacts/)
|
|
82
|
+
|
|
83
|
+
- [Installation](https://capacitor-community.github.io/contacts/#/getting-started-installation)
|
|
84
|
+
|
|
85
|
+
- [API reference](https://capacitor-community.github.io/contacts/#/api)
|
|
86
|
+
|
|
87
|
+
<!-- - [Examples](https://github.com/capacitor-community/contacts-examples) -->
|
|
88
|
+
|
|
89
|
+
## Limitations
|
|
90
|
+
|
|
91
|
+
This plugins only adds support for using the native iOS and Android APIs. If you want to make use of the JavaScript API as well (for a possible webapp) you should implement that separately. Of course it should be possible to integrate this into the plugin in the future. If you want to help out with this, please start a PR.
|
package/android/build.gradle
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
ext {
|
|
2
2
|
junitVersion = project.hasProperty('junitVersion') ? rootProject.ext.junitVersion : '4.13.2'
|
|
3
|
-
androidxAppCompatVersion = project.hasProperty('androidxAppCompatVersion') ? rootProject.ext.androidxAppCompatVersion : '1.
|
|
4
|
-
androidxJunitVersion = project.hasProperty('androidxJunitVersion') ? rootProject.ext.androidxJunitVersion : '1.
|
|
5
|
-
androidxEspressoCoreVersion = project.hasProperty('androidxEspressoCoreVersion') ? rootProject.ext.androidxEspressoCoreVersion : '3.
|
|
3
|
+
androidxAppCompatVersion = project.hasProperty('androidxAppCompatVersion') ? rootProject.ext.androidxAppCompatVersion : '1.7.1'
|
|
4
|
+
androidxJunitVersion = project.hasProperty('androidxJunitVersion') ? rootProject.ext.androidxJunitVersion : '1.3.0'
|
|
5
|
+
androidxEspressoCoreVersion = project.hasProperty('androidxEspressoCoreVersion') ? rootProject.ext.androidxEspressoCoreVersion : '3.7.0'
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
buildscript {
|
|
@@ -11,34 +11,38 @@ buildscript {
|
|
|
11
11
|
mavenCentral()
|
|
12
12
|
}
|
|
13
13
|
dependencies {
|
|
14
|
-
classpath 'com.android.tools.build:gradle:8.
|
|
14
|
+
classpath 'com.android.tools.build:gradle:8.13.0'
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
apply plugin: 'com.android.library'
|
|
19
19
|
|
|
20
20
|
android {
|
|
21
|
-
namespace "
|
|
22
|
-
|
|
21
|
+
namespace = "getcapacitor.community.contacts"
|
|
22
|
+
compileSdkVersion(project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 35)
|
|
23
|
+
|
|
23
24
|
defaultConfig {
|
|
24
|
-
minSdkVersion
|
|
25
|
-
targetSdkVersion
|
|
25
|
+
minSdkVersion(project.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion : 23)
|
|
26
|
+
targetSdkVersion(project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion : 35)
|
|
26
27
|
versionCode 1
|
|
27
28
|
versionName "1.0"
|
|
28
29
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
|
29
30
|
}
|
|
31
|
+
|
|
30
32
|
buildTypes {
|
|
31
33
|
release {
|
|
32
34
|
minifyEnabled false
|
|
33
35
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
|
34
36
|
}
|
|
35
37
|
}
|
|
38
|
+
|
|
36
39
|
lintOptions {
|
|
37
|
-
abortOnError false
|
|
40
|
+
abortOnError = false
|
|
38
41
|
}
|
|
42
|
+
|
|
39
43
|
compileOptions {
|
|
40
|
-
sourceCompatibility JavaVersion.
|
|
41
|
-
targetCompatibility JavaVersion.
|
|
44
|
+
sourceCompatibility JavaVersion.VERSION_21
|
|
45
|
+
targetCompatibility JavaVersion.VERSION_21
|
|
42
46
|
}
|
|
43
47
|
}
|
|
44
48
|
|
|
@@ -47,7 +51,6 @@ repositories {
|
|
|
47
51
|
mavenCentral()
|
|
48
52
|
}
|
|
49
53
|
|
|
50
|
-
|
|
51
54
|
dependencies {
|
|
52
55
|
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
|
53
56
|
implementation project(':capacitor-android')
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
package getcapacitor.community.contacts;
|
|
2
|
+
|
|
3
|
+
import java.util.HashMap;
|
|
4
|
+
|
|
5
|
+
// Helper to enable bidirectional mapping.
|
|
6
|
+
public class BiMap<K, V> {
|
|
7
|
+
|
|
8
|
+
// The following map can be used for retrieving the key belonging to a certain value.
|
|
9
|
+
// This map is essentially the inverted version of `mapForValues`
|
|
10
|
+
private final HashMap<V, K> mapForKeys = new HashMap<>();
|
|
11
|
+
// The following map can be used for retrieving the value belonging to a certain key.
|
|
12
|
+
private final HashMap<K, V> mapForValues;
|
|
13
|
+
|
|
14
|
+
private final K defaultKey;
|
|
15
|
+
private final V defaultValue;
|
|
16
|
+
|
|
17
|
+
BiMap(HashMap<K, V> map, K defaultKey, V defaultValue) {
|
|
18
|
+
this.mapForValues = map;
|
|
19
|
+
|
|
20
|
+
for (HashMap.Entry<K, V> entry : map.entrySet()) {
|
|
21
|
+
K key = entry.getKey();
|
|
22
|
+
V value = entry.getValue();
|
|
23
|
+
this.mapForKeys.put(value, key);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
this.defaultKey = defaultKey;
|
|
27
|
+
this.defaultValue = defaultValue;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
K getKey(V v) {
|
|
31
|
+
K k = this.mapForKeys.get(v);
|
|
32
|
+
if (k == null) {
|
|
33
|
+
return this.defaultKey;
|
|
34
|
+
}
|
|
35
|
+
return k;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
V getValue(K k) {
|
|
39
|
+
V v = this.mapForValues.get(k);
|
|
40
|
+
if (v == null) {
|
|
41
|
+
return this.defaultValue;
|
|
42
|
+
}
|
|
43
|
+
return v;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
package getcapacitor.community.contacts;
|
|
2
|
+
|
|
3
|
+
import android.database.Cursor;
|
|
4
|
+
import android.provider.ContactsContract;
|
|
5
|
+
import android.provider.ContactsContract.CommonDataKinds.Email;
|
|
6
|
+
import android.provider.ContactsContract.CommonDataKinds.Event;
|
|
7
|
+
import android.provider.ContactsContract.CommonDataKinds.Note;
|
|
8
|
+
import android.provider.ContactsContract.CommonDataKinds.Organization;
|
|
9
|
+
import android.provider.ContactsContract.CommonDataKinds.Phone;
|
|
10
|
+
import android.provider.ContactsContract.CommonDataKinds.Photo;
|
|
11
|
+
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
|
|
12
|
+
import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
|
|
13
|
+
import android.provider.ContactsContract.CommonDataKinds.Website;
|
|
14
|
+
import android.util.Base64;
|
|
15
|
+
import androidx.annotation.NonNull;
|
|
16
|
+
import com.getcapacitor.JSArray;
|
|
17
|
+
import com.getcapacitor.JSObject;
|
|
18
|
+
import java.io.BufferedInputStream;
|
|
19
|
+
import java.io.ByteArrayInputStream;
|
|
20
|
+
import java.io.InputStream;
|
|
21
|
+
import java.net.URLConnection;
|
|
22
|
+
|
|
23
|
+
public class ContactPayload {
|
|
24
|
+
|
|
25
|
+
// Id
|
|
26
|
+
private String contactId;
|
|
27
|
+
|
|
28
|
+
// Name
|
|
29
|
+
private JSObject name = new JSObject();
|
|
30
|
+
|
|
31
|
+
// Organization
|
|
32
|
+
private JSObject organization = new JSObject();
|
|
33
|
+
|
|
34
|
+
// Birthday
|
|
35
|
+
private JSObject birthday = new JSObject();
|
|
36
|
+
|
|
37
|
+
// Note
|
|
38
|
+
private String note;
|
|
39
|
+
|
|
40
|
+
// Phones
|
|
41
|
+
private JSArray phones = new JSArray();
|
|
42
|
+
|
|
43
|
+
// Emails
|
|
44
|
+
private JSArray emails = new JSArray();
|
|
45
|
+
|
|
46
|
+
// URLs
|
|
47
|
+
private JSArray urls = new JSArray();
|
|
48
|
+
|
|
49
|
+
// Postal Addresses
|
|
50
|
+
private JSArray postalAddresses = new JSArray();
|
|
51
|
+
|
|
52
|
+
// Image
|
|
53
|
+
private JSObject image = new JSObject();
|
|
54
|
+
|
|
55
|
+
ContactPayload(String contactId) {
|
|
56
|
+
this.contactId = contactId;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
private static @NonNull String getMimetype(byte[] blob) {
|
|
60
|
+
try {
|
|
61
|
+
InputStream is = new BufferedInputStream(new ByteArrayInputStream(blob));
|
|
62
|
+
String mimeType = URLConnection.guessContentTypeFromStream(is);
|
|
63
|
+
if (mimeType == null) {
|
|
64
|
+
return "image/png";
|
|
65
|
+
}
|
|
66
|
+
return mimeType;
|
|
67
|
+
} catch (Exception e) {
|
|
68
|
+
return "image/png";
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
private Integer parseStrToIntSafe(String str) {
|
|
73
|
+
try {
|
|
74
|
+
return Integer.parseInt(str);
|
|
75
|
+
} catch (NumberFormatException e) {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
private Boolean getBooleanByColumnName(Cursor cursor, String columnName) {
|
|
81
|
+
int index = cursor.getColumnIndex(columnName);
|
|
82
|
+
if (index >= 0) {
|
|
83
|
+
int result = cursor.getInt(index);
|
|
84
|
+
return result == 1;
|
|
85
|
+
}
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
private String getStringByColumnName(Cursor cursor, String columnName) {
|
|
90
|
+
int index = cursor.getColumnIndex(columnName);
|
|
91
|
+
if (index >= 0) {
|
|
92
|
+
return cursor.getString(index);
|
|
93
|
+
}
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
private Integer getIntByColumnName(Cursor cursor, String columnName) {
|
|
98
|
+
int index = cursor.getColumnIndex(columnName);
|
|
99
|
+
if (index >= 0) {
|
|
100
|
+
return cursor.getInt(index);
|
|
101
|
+
}
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
private String getBase64ByColumnName(Cursor cursor, String columnName) {
|
|
106
|
+
int index = cursor.getColumnIndex(columnName);
|
|
107
|
+
if (index >= 0) {
|
|
108
|
+
byte[] blob = cursor.getBlob(index);
|
|
109
|
+
if (blob != null) {
|
|
110
|
+
String mimeType = getMimetype(blob);
|
|
111
|
+
String encodedImage = Base64.encodeToString(blob, Base64.NO_WRAP);
|
|
112
|
+
return "data:" + mimeType + ";base64," + encodedImage;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
public void fillDataByCursor(@NonNull Cursor cursor) {
|
|
119
|
+
String mimeType = getStringByColumnName(cursor, ContactsContract.Data.MIMETYPE);
|
|
120
|
+
|
|
121
|
+
if (mimeType == null) {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
switch (mimeType) {
|
|
126
|
+
// Name
|
|
127
|
+
case StructuredName.CONTENT_ITEM_TYPE:
|
|
128
|
+
name.put("display", getStringByColumnName(cursor, StructuredName.DISPLAY_NAME));
|
|
129
|
+
name.put("given", getStringByColumnName(cursor, StructuredName.GIVEN_NAME));
|
|
130
|
+
name.put("middle", getStringByColumnName(cursor, StructuredName.MIDDLE_NAME));
|
|
131
|
+
name.put("family", getStringByColumnName(cursor, StructuredName.FAMILY_NAME));
|
|
132
|
+
name.put("prefix", getStringByColumnName(cursor, StructuredName.PREFIX));
|
|
133
|
+
name.put("suffix", getStringByColumnName(cursor, StructuredName.SUFFIX));
|
|
134
|
+
break;
|
|
135
|
+
// Organization
|
|
136
|
+
case Organization.CONTENT_ITEM_TYPE:
|
|
137
|
+
organization.put("company", getStringByColumnName(cursor, Organization.COMPANY));
|
|
138
|
+
organization.put("jobTitle", getStringByColumnName(cursor, Organization.TITLE));
|
|
139
|
+
organization.put("department", getStringByColumnName(cursor, Organization.DEPARTMENT));
|
|
140
|
+
break;
|
|
141
|
+
// Birthday
|
|
142
|
+
case Event.CONTENT_ITEM_TYPE:
|
|
143
|
+
Integer eventType = getIntByColumnName(cursor, Event.TYPE);
|
|
144
|
+
if (eventType != null && eventType == Event.TYPE_BIRTHDAY) {
|
|
145
|
+
String birthdayString = getStringByColumnName(cursor, Event.START_DATE);
|
|
146
|
+
|
|
147
|
+
if (birthdayString != null) {
|
|
148
|
+
// Normally the date is formatted as "yyyy-mm-dd"
|
|
149
|
+
// But it's possible to not have a year saved to the birthday,
|
|
150
|
+
// then it's formatted like "--mm-dd".
|
|
151
|
+
// So we'll have to rectify that:
|
|
152
|
+
birthdayString = birthdayString.replace("--", "");
|
|
153
|
+
|
|
154
|
+
// Next we'll split the string into pieces:
|
|
155
|
+
String[] splittedBirthdayString = birthdayString.split("-");
|
|
156
|
+
|
|
157
|
+
if (splittedBirthdayString.length == 2) {
|
|
158
|
+
// Birthday is formatted like "mm-dd"
|
|
159
|
+
birthday.put("month", parseStrToIntSafe(splittedBirthdayString[0]));
|
|
160
|
+
birthday.put("day", parseStrToIntSafe(splittedBirthdayString[1]));
|
|
161
|
+
} else if (splittedBirthdayString.length == 3) {
|
|
162
|
+
// Birthday is formatted like "yyyy-mm-dd"
|
|
163
|
+
birthday.put("year", parseStrToIntSafe(splittedBirthdayString[0]));
|
|
164
|
+
birthday.put("month", parseStrToIntSafe(splittedBirthdayString[1]));
|
|
165
|
+
birthday.put("day", parseStrToIntSafe(splittedBirthdayString[2]));
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
break;
|
|
170
|
+
// Note
|
|
171
|
+
case Note.CONTENT_ITEM_TYPE:
|
|
172
|
+
note = getStringByColumnName(cursor, Note.NOTE);
|
|
173
|
+
break;
|
|
174
|
+
// Phones
|
|
175
|
+
case Phone.CONTENT_ITEM_TYPE:
|
|
176
|
+
String number = getStringByColumnName(cursor, Phone.NUMBER);
|
|
177
|
+
Integer phoneType = getIntByColumnName(cursor, Phone.TYPE);
|
|
178
|
+
if (number != null && phoneType != null) {
|
|
179
|
+
JSObject phoneObject = new JSObject();
|
|
180
|
+
phoneObject.put("type", Contacts.phoneTypeMap.getKey(phoneType));
|
|
181
|
+
phoneObject.put("label", getStringByColumnName(cursor, Phone.LABEL));
|
|
182
|
+
phoneObject.put("isPrimary", getBooleanByColumnName(cursor, Phone.IS_PRIMARY));
|
|
183
|
+
phoneObject.put("number", number);
|
|
184
|
+
phones.put(phoneObject);
|
|
185
|
+
}
|
|
186
|
+
break;
|
|
187
|
+
// Emails
|
|
188
|
+
case Email.CONTENT_ITEM_TYPE:
|
|
189
|
+
String address = getStringByColumnName(cursor, Email.ADDRESS);
|
|
190
|
+
Integer emailType = getIntByColumnName(cursor, Email.TYPE);
|
|
191
|
+
if (address != null && emailType != null) {
|
|
192
|
+
JSObject emailObject = new JSObject();
|
|
193
|
+
emailObject.put("type", Contacts.emailTypeMap.getKey(emailType));
|
|
194
|
+
emailObject.put("label", getStringByColumnName(cursor, Email.LABEL));
|
|
195
|
+
emailObject.put("isPrimary", getBooleanByColumnName(cursor, Email.IS_PRIMARY));
|
|
196
|
+
emailObject.put("address", address);
|
|
197
|
+
emails.put(emailObject);
|
|
198
|
+
}
|
|
199
|
+
break;
|
|
200
|
+
// URLs
|
|
201
|
+
case Website.CONTENT_ITEM_TYPE:
|
|
202
|
+
String url = getStringByColumnName(cursor, Website.URL);
|
|
203
|
+
urls.put(url);
|
|
204
|
+
break;
|
|
205
|
+
// Postal Addresses
|
|
206
|
+
case StructuredPostal.CONTENT_ITEM_TYPE:
|
|
207
|
+
Integer postalAddressType = getIntByColumnName(cursor, StructuredPostal.TYPE);
|
|
208
|
+
if (postalAddressType != null) {
|
|
209
|
+
JSObject postalAddressObject = new JSObject();
|
|
210
|
+
postalAddressObject.put("type", Contacts.postalAddressTypeMap.getKey(postalAddressType));
|
|
211
|
+
postalAddressObject.put("label", getStringByColumnName(cursor, StructuredPostal.LABEL));
|
|
212
|
+
postalAddressObject.put("isPrimary", getBooleanByColumnName(cursor, StructuredPostal.IS_PRIMARY));
|
|
213
|
+
postalAddressObject.put("formatted", getStringByColumnName(cursor, StructuredPostal.FORMATTED_ADDRESS));
|
|
214
|
+
postalAddressObject.put("street", getStringByColumnName(cursor, StructuredPostal.STREET));
|
|
215
|
+
postalAddressObject.put("neighborhood", getStringByColumnName(cursor, StructuredPostal.NEIGHBORHOOD));
|
|
216
|
+
postalAddressObject.put("city", getStringByColumnName(cursor, StructuredPostal.CITY));
|
|
217
|
+
postalAddressObject.put("region", getStringByColumnName(cursor, StructuredPostal.REGION));
|
|
218
|
+
postalAddressObject.put("postcode", getStringByColumnName(cursor, StructuredPostal.POSTCODE));
|
|
219
|
+
postalAddressObject.put("country", getStringByColumnName(cursor, StructuredPostal.COUNTRY));
|
|
220
|
+
postalAddresses.put(postalAddressObject);
|
|
221
|
+
}
|
|
222
|
+
break;
|
|
223
|
+
// Image
|
|
224
|
+
case Photo.CONTENT_ITEM_TYPE:
|
|
225
|
+
String base64String = getBase64ByColumnName(cursor, Photo.PHOTO);
|
|
226
|
+
if (base64String != null) {
|
|
227
|
+
image.put("base64String", base64String);
|
|
228
|
+
}
|
|
229
|
+
break;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
public JSObject getJSObject() {
|
|
234
|
+
JSObject contact = new JSObject();
|
|
235
|
+
|
|
236
|
+
// Id
|
|
237
|
+
contact.put("contactId", contactId);
|
|
238
|
+
|
|
239
|
+
// Name
|
|
240
|
+
if (name.length() > 0) {
|
|
241
|
+
contact.put("name", name);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// Organization
|
|
245
|
+
if (organization.length() > 0) {
|
|
246
|
+
contact.put("organization", organization);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// Birthday
|
|
250
|
+
if (birthday.length() > 0) {
|
|
251
|
+
contact.put("birthday", birthday);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// Note
|
|
255
|
+
if (note != null) {
|
|
256
|
+
contact.put("note", note);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// Phones
|
|
260
|
+
if (phones.length() > 0) {
|
|
261
|
+
contact.put("phones", phones);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// Emails
|
|
265
|
+
if (emails.length() > 0) {
|
|
266
|
+
contact.put("emails", emails);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// URLs
|
|
270
|
+
if (urls.length() > 0) {
|
|
271
|
+
contact.put("urls", urls);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// Postal Addresses
|
|
275
|
+
if (postalAddresses.length() > 0) {
|
|
276
|
+
contact.put("postalAddresses", postalAddresses);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// Image
|
|
280
|
+
if (image.length() > 0) {
|
|
281
|
+
contact.put("image", image);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
return contact;
|
|
285
|
+
}
|
|
286
|
+
}
|