Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions android/.settings/org.eclipse.buildship.core.prefs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
arguments=--init-script /var/folders/0h/1wd_6skn0h3gppnj15t0tbl40000gn/T/d146c9752a26f79b52047fb6dc6ed385d064e120494f96f08ca63a317c41f94c.gradle
auto.sync=false
build.scans.enabled=false
connection.gradle.distribution=GRADLE_DISTRIBUTION(VERSION(7.4.2))
connection.project.dir=
eclipse.preferences.version=1
gradle.user.home=
java.home=/Library/Java/JavaVirtualMachines/jdk-23.jdk/Contents/Home
jvm.arguments=
offline.mode=false
override.workspace.settings=true
show.console.view=true
show.executions.view=true
9 changes: 5 additions & 4 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ buildscript {
}

dependencies {
classpath 'com.android.tools.build:gradle:4.0.1'
classpath 'com.android.tools.build:gradle:8.1.0'
}
}

Expand All @@ -20,13 +20,14 @@ rootProject.allprojects {
}

apply plugin: 'com.android.library'

android {
compileSdkVersion 30

namespace "flutter.plugins.contactsservice.contactsservice"
compileSdk flutter.compileSdkVersion
ndkVersion flutter.ndkVersion
defaultConfig {
minSdkVersion 16
targetSdkVersion 30
compileSdkVersion 35
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
Expand Down
3 changes: 3 additions & 0 deletions android/gradle.properties
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
org.gradle.jvmargs=-Xmx1536M
android.useAndroidX=true
android.enableJetifier=true

2 changes: 1 addition & 1 deletion android/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip
Original file line number Diff line number Diff line change
Expand Up @@ -287,16 +287,21 @@ public boolean onActivityResult(int requestCode, int resultCode, Intent intent)
return true;
}
Uri contactUri = intent.getData();
if (intent != null){
Cursor cursor = contentResolver.query(contactUri, null, null, null, null);
if (cursor.moveToFirst()) {
String id = contactUri.getLastPathSegment();
getContacts("openDeviceContactPicker", id, false, false, false, localizedLabels, this.result);
if (intent != null) {
Cursor cursor = contentResolver.query(contactUri, null, null, null, null);
if (cursor != null && cursor.moveToFirst()) {
String id = contactUri.getLastPathSegment();
getContacts("openDeviceContactPicker", id, false, false, false, localizedLabels, this.result);
} else {
Log.e(LOG_TAG, "onActivityResult - cursor.moveToFirst() returns false");
finishWithResult(FORM_OPERATION_CANCELED);
}
if (cursor != null) {
cursor.close();
}
} else {
Log.e(LOG_TAG, "onActivityResult - cursor.moveToFirst() returns false");
finishWithResult(FORM_OPERATION_CANCELED);
}}else{return true;}
cursor.close();
return true;
}
return true;
}

Expand Down
5 changes: 4 additions & 1 deletion example/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@ apply plugin: 'com.android.application'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"

android {
compileSdkVersion 30

namespace "flutter.plugins.contactsservice.contactsserviceexample"
compileSdk flutter.compileSdkVersion
ndkVersion flutter.ndkVersion
lintOptions {
disable 'InvalidPackage'
}
Expand All @@ -26,6 +28,7 @@ android {
applicationId "flutter.plugins.contactsservice.contactsserviceexample"
minSdkVersion 16
targetSdkVersion 30
compileSdkVersion 35
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
Expand Down
82 changes: 40 additions & 42 deletions example/lib/contacts_list_page.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:contacts_service_example/main.dart';

import 'package:contacts_service/contacts_service.dart';
import 'package:contacts_service_example/main.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';

class ContactListPage extends StatefulWidget {
Expand All @@ -11,7 +9,7 @@ class ContactListPage extends StatefulWidget {
}

class _ContactListPageState extends State<ContactListPage> {
List<Contact> _contacts;
List<Contact>? _contacts;

@override
void initState() {
Expand Down Expand Up @@ -39,8 +37,9 @@ class _ContactListPageState extends State<ContactListPage> {
}

void updateContact() async {
Contact ninja = _contacts
.firstWhere((contact) => contact.familyName.startsWith("Ninja"));
Contact ninja = _contacts?.firstWhere(
(contact) => contact.familyName?.startsWith("Ninja") ?? false) ??
Contact();
ninja.avatar = null;
await ContactsService.updateContact(ninja);

Expand Down Expand Up @@ -90,7 +89,7 @@ class _ContactListPageState extends State<ContactListPage> {
? ListView.builder(
itemCount: _contacts?.length ?? 0,
itemBuilder: (BuildContext context, int index) {
Contact c = _contacts?.elementAt(index);
Contact c = _contacts?.elementAt(index) ?? Contact();
return ListTile(
onTap: () {
Navigator.of(context).push(MaterialPageRoute(
Expand All @@ -100,8 +99,8 @@ class _ContactListPageState extends State<ContactListPage> {
contactOnDeviceHasBeenUpdated,
)));
},
leading: (c.avatar != null && c.avatar.length > 0)
? CircleAvatar(backgroundImage: MemoryImage(c.avatar))
leading: (c.avatar != null && ((c.avatar?.length ?? 0) > 0))
? CircleAvatar(backgroundImage: MemoryImage(c.avatar!))
: CircleAvatar(child: Text(c.initials())),
title: Text(c.displayName ?? ""),
);
Expand All @@ -116,14 +115,14 @@ class _ContactListPageState extends State<ContactListPage> {

void contactOnDeviceHasBeenUpdated(Contact contact) {
this.setState(() {
var id = _contacts.indexWhere((c) => c.identifier == contact.identifier);
_contacts[id] = contact;
var id = _contacts?.indexWhere((c) => c.identifier == contact.identifier);
_contacts?[id ?? 0] = contact;
});
}
}

class ContactDetailsPage extends StatelessWidget {
ContactDetailsPage(this._contact, {this.onContactDeviceSave});
ContactDetailsPage(this._contact, {required this.onContactDeviceSave});

final Contact _contact;
final Function(Contact) onContactDeviceSave;
Expand All @@ -132,9 +131,7 @@ class ContactDetailsPage extends StatelessWidget {
try {
var contact = await ContactsService.openExistingContact(_contact,
iOSLocalizedLabels: iOSLocalizedLabels);
if (onContactDeviceSave != null) {
onContactDeviceSave(contact);
}
onContactDeviceSave(contact);
Navigator.of(context).pop();
} on FormOperationException catch (e) {
switch (e.errorCode) {
Expand Down Expand Up @@ -202,7 +199,8 @@ class ContactDetailsPage extends StatelessWidget {
ListTile(
title: Text("Birthday"),
trailing: Text(_contact.birthday != null
? DateFormat('dd-MM-yyyy').format(_contact.birthday)
? DateFormat('dd-MM-yyyy')
.format(_contact.birthday ?? DateTime.now())
: ""),
),
ListTile(
Expand All @@ -219,9 +217,9 @@ class ContactDetailsPage extends StatelessWidget {
? _contact.androidAccountType.toString()
: ""),
),
AddressesTile(_contact.postalAddresses),
ItemsTile("Phones", _contact.phones),
ItemsTile("Emails", _contact.emails)
AddressesTile(_contact.postalAddresses ?? []),
ItemsTile("Phones", _contact.phones ?? []),
ItemsTile("Emails", _contact.emails ?? [])
],
),
),
Expand Down Expand Up @@ -323,7 +321,7 @@ class _AddContactPageState extends State<AddContactPage> {
actions: <Widget>[
TextButton(
onPressed: () {
_formKey.currentState.save();
_formKey.currentState?.save();
contact.postalAddresses = [address];
ContactsService.addContact(contact);
Navigator.of(context).pop();
Expand Down Expand Up @@ -407,7 +405,7 @@ class _AddContactPageState extends State<AddContactPage> {
}

class UpdateContactsPage extends StatefulWidget {
UpdateContactsPage({@required this.contact});
UpdateContactsPage({required this.contact});

final Contact contact;

Expand All @@ -416,7 +414,7 @@ class UpdateContactsPage extends StatefulWidget {
}

class _UpdateContactsPageState extends State<UpdateContactsPage> {
Contact contact;
Contact? contact;
PostalAddress address = PostalAddress(label: "Home");
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();

Expand All @@ -438,9 +436,9 @@ class _UpdateContactsPageState extends State<UpdateContactsPage> {
color: Colors.white,
),
onPressed: () async {
_formKey.currentState.save();
contact.postalAddresses = [address];
await ContactsService.updateContact(contact);
_formKey.currentState?.save();
contact?.postalAddresses = [address];
await ContactsService.updateContact(contact ?? Contact());
Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (context) => ContactListPage()));
},
Expand All @@ -454,51 +452,51 @@ class _UpdateContactsPageState extends State<UpdateContactsPage> {
child: ListView(
children: <Widget>[
TextFormField(
initialValue: contact.givenName ?? "",
initialValue: contact?.givenName ?? "",
decoration: const InputDecoration(labelText: 'First name'),
onSaved: (v) => contact.givenName = v,
onSaved: (v) => contact?.givenName = v,
),
TextFormField(
initialValue: contact.middleName ?? "",
initialValue: contact?.middleName ?? "",
decoration: const InputDecoration(labelText: 'Middle name'),
onSaved: (v) => contact.middleName = v,
onSaved: (v) => contact?.middleName = v,
),
TextFormField(
initialValue: contact.familyName ?? "",
initialValue: contact?.familyName ?? "",
decoration: const InputDecoration(labelText: 'Last name'),
onSaved: (v) => contact.familyName = v,
onSaved: (v) => contact?.familyName = v,
),
TextFormField(
initialValue: contact.prefix ?? "",
initialValue: contact?.prefix ?? "",
decoration: const InputDecoration(labelText: 'Prefix'),
onSaved: (v) => contact.prefix = v,
onSaved: (v) => contact?.prefix = v,
),
TextFormField(
initialValue: contact.suffix ?? "",
initialValue: contact?.suffix ?? "",
decoration: const InputDecoration(labelText: 'Suffix'),
onSaved: (v) => contact.suffix = v,
onSaved: (v) => contact?.suffix = v,
),
TextFormField(
decoration: const InputDecoration(labelText: 'Phone'),
onSaved: (v) =>
contact.phones = [Item(label: "mobile", value: v)],
contact?.phones = [Item(label: "mobile", value: v)],
keyboardType: TextInputType.phone,
),
TextFormField(
decoration: const InputDecoration(labelText: 'E-mail'),
onSaved: (v) =>
contact.emails = [Item(label: "work", value: v)],
contact?.emails = [Item(label: "work", value: v)],
keyboardType: TextInputType.emailAddress,
),
TextFormField(
initialValue: contact.company ?? "",
initialValue: contact?.company ?? "",
decoration: const InputDecoration(labelText: 'Company'),
onSaved: (v) => contact.company = v,
onSaved: (v) => contact?.company = v,
),
TextFormField(
initialValue: contact.jobTitle ?? "",
initialValue: contact?.jobTitle ?? "",
decoration: const InputDecoration(labelText: 'Job'),
onSaved: (v) => contact.jobTitle = v,
onSaved: (v) => contact?.jobTitle = v,
),
TextFormField(
initialValue: address.street ?? "",
Expand Down
9 changes: 4 additions & 5 deletions example/lib/contacts_picker_page.dart
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import 'package:contacts_service/contacts_service.dart';
import 'package:contacts_service_example/main.dart';
import 'package:flutter/material.dart';

import 'package:contacts_service/contacts_service.dart';

class ContactPickerPage extends StatefulWidget {
@override
_ContactPickerPageState createState() => _ContactPickerPageState();
}

class _ContactPickerPageState extends State<ContactPickerPage> {
Contact _contact;
Contact? _contact;

@override
void initState() {
Expand All @@ -18,7 +17,7 @@ class _ContactPickerPageState extends State<ContactPickerPage> {

Future<void> _pickContact() async {
try {
final Contact contact = await ContactsService.openDeviceContactPicker(
final Contact? contact = await ContactsService.openDeviceContactPicker(
iOSLocalizedLabels: iOSLocalizedLabels);
setState(() {
_contact = contact;
Expand All @@ -40,7 +39,7 @@ class _ContactPickerPageState extends State<ContactPickerPage> {
onPressed: _pickContact,
),
if (_contact != null)
Text('Contact selected: ${_contact.displayName}'),
Text('Contact selected: ${_contact?.displayName}'),
],
)),
);
Expand Down
6 changes: 3 additions & 3 deletions example/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
name: contacts_service_example
description: Demonstrates how to use the contacts_service plugin.
environment:
sdk: '>=2.10.0 <3.0.0'
sdk: '>=2.12.0 <3.0.0'
dependencies:
flutter:
sdk: flutter

# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2
intl: ^0.17.0
cupertino_icons: ^1.0.8
intl: ^0.20.2

dev_dependencies:
flutter_test:
Expand Down