2
votes

Actually I am building a card reader application in which data is coming from the ML model and get stored in the mycontrollers function. But on using ContactsService.addContact(contact); I am getting error. Although contact is saved in the app but not in the phone's contact list.

code:

 void saveContactInPhone() {
try {

  print("saving Conatct");
  Contact contact = Contact();
    print("fi");
    contact.displayName = myController1.text ; 
    contact.phones = [Item(label: "mobile", value: myController4.text)];
    // contact.emails = [Item(label: "email", value: myController3.text)];
    contact.company = myController2.text;
    print("fi2");

  ContactsService.addContact(contact);
  print("object");      

} catch (e) {
  print(e);
}

}

Error:

I/flutter ( 1615): form init

I/flutter ( 1615): /data/user/0/com.example.camera_app/app_flutter/2020-05-29 23:35:12.398628.png I/flutter ( 1615): Going Image I/flutter ( 1615): 404 I/flutter ( 1615): Image Send I/flutter ( 1615): form come listenForSinglecontact I/flutter ( 1615): saving I/flutter ( 1615): fi I/flutter ( 1615): fi2 I/flutter ( 1615): object E/flutter ( 1615): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: FormatException: Invalid envelope E/flutter ( 1615): #0 StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:571:7) E/flutter ( 1615): #1 MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:156:18) E/flutter ( 1615): E/flutter ( 1615): #2 MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:329:12) E/flutter ( 1615): #3 ContactsService.addContact (package:contacts_service/contacts_service.dart:83:16) E/flutter ( 1615): #4 _FormState.saveData (package:camera_app/screens/form.dart:249:23) E/flutter ( 1615): #5 _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:779:19) E/flutter ( 1615): #6 _InkResponseState.build. (package:flutter/src/material/ink_well.dart:862:36) E/flutter ( 1615): #7 GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:182:24) E/flutter ( 1615): #8 TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:504:11) E/flutter ( 1615): #9 BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:282:5) E/flutter ( 1615): #10 BaseTapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:217:7) E/flutter ( 1615): #11 PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/gestures/recognizer.dart:475:9) E/flutter ( 1615): #12 PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:76:12) E/flutter ( 1615): #13 PointerRouter._dispatchEventToRoutes. (package:flutter/src/gestures/pointer_router.dart:122:9) E/flutter ( 1615): #14 _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:379:8) E/flutter ( 1615): #15 PointerRouter._dispatchEventToRoutes (package:flutter/src/gestures/pointer_router.dart:120:18) E/flutter ( 1615): #16 PointerRouter.route (package:flutter/src/gestures/pointer_router.dart:106:7) E/flutter ( 1615): #17 GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:218:19) E/flutter ( 1615): #18 GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:198:22) E/flutter ( 1615): #19 GestureBinding._handlePointerEvent (package:flutter/src/gestures/binding.dart:156:7) E/flutter ( 1615): #20 GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:102:7) E/flutter ( 1615): #21 GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:86:7)

1

1 Answers

1
votes

Actually I was missing the permissions part. Ohh I am such a newbie in Flutter.

This worked for me finally for saving a contact in MAin Contacts or phone directory.

So let's use contacts_service 0.4.6 for it. First, add dependency as :

dependencies:  
contacts_service: ^0.4.6

Permissions:

For Android Add the following permissions to your AndroidManifest.xml:

<uses-permission android:name="android.permission.READ_CONTACTS" />  
<uses-permission android:name="android.permission.WRITE_CONTACTS" />  

For iOS Set the NSContactsUsageDescription in your Info.plist file

<key>NSContactsUsageDescription</key>  
<string>This app requires contacts access to function properly.</string>  

Import library:

import 'package:contacts_service/contacts_service.dart'; 

Basically,

 final myController1 = TextEditingController();
 final myController2 = TextEditingController();
 ...

These are variables used to store the value entered by the user in Textfield or Textform. The value can be query by using myController1.text We can also store Contact class objects as:

   newContact.givenName = "Some name";
            newContact.emails = [
              Item(label: "email", value: "[email protected]")
            ];
            newContact.company = myController2.text;
            newContact.phones = [
              Item(label: "mobile", value: "123456789")
            ];

Code for just saving contact:

     Future<void> saveContactInPhone() async {
    try {

      print("saving Conatct");
      PermissionStatus permission = await Permission.contacts.status;

    if (permission != PermissionStatus.granted) {
      await Permission.contacts.request();
      PermissionStatus permission = await Permission.contacts.status;

      if (permission == PermissionStatus.granted) {
        Contact newContact = new Contact();
        newContact.givenName = myController1.text;
        newContact.emails = [
          Item(label: "email", value: myController3.text)
        ];
        newContact.company = myController2.text;
        newContact.phones = [
          Item(label: "mobile", value: myController4.text)
        ];
        newContact.postalAddresses = [
          PostalAddress(region: myController6.text)
        ];
        await ContactsService.addContact(newContact);

      } else {
        //_handleInvalidPermissions(context);
      }
    } else {
      Contact newContact = new Contact();
        newContact.givenName = myController1.text;
        newContact.emails = [
          Item(label: "email", value: myController3.text)
        ];
        newContact.company = myController2.text;
        newContact.phones = [
          Item(label: "mobile", value: myController4.text)
        ];
        newContact.postalAddresses = [
          PostalAddress(region: myController6.text)
        ];
        await ContactsService.addContact(newContact);
    }
      print("object");      

    } catch (e) {
      print(e);
    }
  }

Similarily I found too much difficulty in reflecting the changes on the actual phone directory. So I came up with this solution:

Future<void> saveContactInPhone() async {
    try {
      print("saving Conatct");
      PermissionStatus permission = await Permission.contacts.status;

      if (permission != PermissionStatus.granted) {
        await Permission.contacts.request();
        PermissionStatus permission = await Permission.contacts.status;

        if (permission == PermissionStatus.granted) {
          if (widget.checkPrev == 'for_edit') {
            // Contact updatedContact = new Contact();
            Iterable<Contact> updatedContact =
                await ContactsService.getContacts(query: myController1.text);

            Contact updatedContact1 = new Contact();
            updatedContact1 = updatedContact.first;
            await ContactsService.deleteContact(updatedContact1);
            Contact newContact = new Contact();
            newContact.givenName = myController1.text;
            newContact.emails = [
              Item(label: "email", value: myController3.text)
            ];
            newContact.company = myController2.text;
            newContact.phones = [
              Item(label: "mobile", value: myController4.text)
            ];
            newContact.postalAddresses = [
              PostalAddress(region: myController6.text)
            ];
            await ContactsService.addContact(newContact);
          } else if (widget.checkPrev == 'from_btn') {
            Contact newContact = new Contact();
            newContact.givenName = myController1.text;
            newContact.emails = [
              Item(label: "email", value: myController3.text)
            ];
            newContact.company = myController2.text;
            newContact.phones = [
              Item(label: "mobile", value: myController4.text)
            ];
            newContact.postalAddresses = [
              PostalAddress(region: myController6.text)
            ];
            await ContactsService.addContact(newContact);
          }
        }
      } else {
        if (widget.checkPrev == 'for_edit') {
          // Contact updatedContact = new Contact();
          Iterable<Contact> updatedContact =
              await ContactsService.getContacts(query: myController1.text);

          await ContactsService.deleteContact(updatedContact.first);
          // Contact updatedContact1 = new Contact();
          // updatedContact1= updatedContact.first;
          Contact newContact = new Contact();
          newContact.givenName = myController1.text;
          newContact.emails = [Item(label: "email", value: myController3.text)];
          newContact.company = myController2.text;
          newContact.phones = [
            Item(label: "mobile", value: myController4.text)
          ];
          newContact.postalAddresses = [
            PostalAddress(region: myController6.text)
          ];
          await ContactsService.addContact(newContact);
        } else if (widget.checkPrev == 'from_btn') {
          Contact newContact = new Contact();
          newContact.givenName = myController1.text;
          newContact.emails = [Item(label: "email", value: myController3.text)];
          newContact.company = myController2.text;
          newContact.phones = [
            Item(label: "mobile", value: myController4.text)
          ];
          newContact.postalAddresses = [
            PostalAddress(region: myController6.text)
          ];
          await ContactsService.addContact(newContact);
        }
      }
    } catch (e) {
      print(e);
    }
  }

This will save a contact as well as edit the contact whenever make changes in the current app.