diff --git a/android/build.gradle b/android/build.gradle index 8fc020d..b4aacdd 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -26,12 +26,12 @@ rootProject.allprojects { apply plugin: 'com.android.library' android { - compileSdkVersion 25 - buildToolsVersion '25.0.3' + compileSdkVersion 28 + buildToolsVersion '28.0.3' defaultConfig { minSdkVersion 16 - targetSdkVersion 25 + targetSdkVersion 28 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" diff --git a/android/src/main/java/net/goderbauer/flutter/contactpicker/ContactPickerPlugin.java b/android/src/main/java/net/goderbauer/flutter/contactpicker/ContactPickerPlugin.java index 1c4c373..4367e3f 100644 --- a/android/src/main/java/net/goderbauer/flutter/contactpicker/ContactPickerPlugin.java +++ b/android/src/main/java/net/goderbauer/flutter/contactpicker/ContactPickerPlugin.java @@ -40,6 +40,7 @@ private ContactPickerPlugin(Activity activity) { @Override public void onMethodCall(MethodCall call, Result result) { + Uri intentUri; if (call.method.equals("selectContact")) { if (pendingResult != null) { pendingResult.error("multiple_requests", "Cancelled by a second request.", null); @@ -47,7 +48,22 @@ public void onMethodCall(MethodCall call, Result result) { } pendingResult = result; - Intent i = new Intent(Intent.ACTION_PICK, ContactsContract.CommonDataKinds.Phone.CONTENT_URI); + String requestType = "contacts"; + if (call.hasArgument("type")) { + requestType = call.argument("type"); + } + + switch (requestType) { + case "phone": + intentUri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI; + break; + case "contacts": + default: + intentUri = ContactsContract.Contacts.CONTENT_URI; + break; + } + + Intent i = new Intent(Intent.ACTION_PICK, intentUri); activity.startActivityForResult(i, PICK_CONTACT); } else { result.notImplemented(); @@ -68,17 +84,20 @@ public boolean onActivityResult(int requestCode, int resultCode, Intent data) { Cursor cursor = activity.getContentResolver().query(contactUri, null, null, null, null); cursor.moveToFirst(); - int phoneType = cursor.getInt(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE)); - String customLabel = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.LABEL)); - String label = (String) ContactsContract.CommonDataKinds.Email.getTypeLabel(activity.getResources(), phoneType, customLabel); - String number = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); - String fullName = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)); - HashMap phoneNumber = new HashMap<>(); - phoneNumber.put("number", number); - phoneNumber.put("label", label); - HashMap contact = new HashMap<>(); + + int phoneTypeIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE); + if (phoneTypeIndex != -1) { + int phoneType = cursor.getInt(phoneTypeIndex); + String customLabel = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.LABEL)); + String label = (String) ContactsContract.CommonDataKinds.Email.getTypeLabel(activity.getResources(), phoneType, customLabel); + String number = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); + phoneNumber.put("number", number); + phoneNumber.put("label", label); + } + String fullName = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)); + contact.put("fullName", fullName); contact.put("phoneNumber", phoneNumber); diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index 255ae05..d9251cd 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -15,8 +15,8 @@ apply plugin: 'com.android.application' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { - compileSdkVersion 25 - buildToolsVersion '25.0.3' + compileSdkVersion 28 + buildToolsVersion '28.0.3' lintOptions { disable 'InvalidPackage' @@ -26,7 +26,7 @@ android { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "com.yourcompany.contactpickerexample" minSdkVersion 16 - targetSdkVersion 25 + targetSdkVersion 28 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" @@ -46,7 +46,7 @@ flutter { } dependencies { - androidTestCompile 'com.android.support:support-annotations:25.4.0' - androidTestCompile 'com.android.support.test:runner:0.5' - androidTestCompile 'com.android.support.test:rules:0.5' + androidTestCompile 'com.android.support:support-annotations:28.0.0' + androidTestCompile 'com.android.support.test:runner:1.0.2' + androidTestCompile 'com.android.support.test:rules:1.0.2' } diff --git a/example/lib/main.dart b/example/lib/main.dart index 1f635ef..1358dea 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -31,7 +31,7 @@ class _MyAppState extends State { children: [ new MaterialButton( color: Colors.blue, - child: new Text("CLICK ME"), + child: new Text("Phone"), onPressed: () async { Contact contact = await _contactPicker.selectContact(); setState(() { @@ -39,6 +39,16 @@ class _MyAppState extends State { }); }, ), + new MaterialButton( + color: Colors.blue, + child: new Text("Contact"), + onPressed: () async { + Contact contact = await _contactPicker.selectContactName(); + setState(() { + _contact = contact; + }); + }, + ), new Text( _contact == null ? 'No contact selected.' : _contact.toString(), ), diff --git a/lib/contact_picker.dart b/lib/contact_picker.dart deleted file mode 100644 index 49734e0..0000000 --- a/lib/contact_picker.dart +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2017 Michael Goderbauer. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'dart:async'; - -import 'package:flutter/services.dart'; - -/// Entry point for the ContactPicker plugin. -/// -/// Call [selectContact] to bring up a dialog where the user can pick a contact -/// from his/her address book. -class ContactPicker { - static const MethodChannel _channel = const MethodChannel('contact_picker'); - - /// Brings up a dialog where the user can select a contact from his/her - /// address book. - /// - /// Returns the [Contact] selected by the user, or `null` if the user canceled - /// out of the dialog. - Future selectContact() async { - final Map result = - await _channel.invokeMethod('selectContact'); - if (result == null) { - return null; - } - return new Contact.fromMap(result); - } -} - -/// Represents a contact selected by the user. -class Contact { - Contact({this.fullName, this.phoneNumber}); - - factory Contact.fromMap(Map map) => new Contact( - fullName: map['fullName'], - phoneNumber: new PhoneNumber.fromMap(map['phoneNumber'])); - - /// The full name of the contact, e.g. "Dr. Daniel Higgens Jr.". - final String fullName; - - /// The phone number of the contact. - final PhoneNumber phoneNumber; - - @override - String toString() => '$fullName: $phoneNumber'; -} - -/// Represents a phone number selected by the user. -class PhoneNumber { - PhoneNumber({this.number, this.label}); - - factory PhoneNumber.fromMap(Map map) => - new PhoneNumber(number: map['number'], label: map['label']); - - /// The formatted phone number, e.g. "+1 (555) 555-5555" - final String number; - - /// The label associated with the phone number, e.g. "home" or "work". - final String label; - - @override - String toString() => '$number ($label)'; -}