skip to Main Content

My code is the file name is interface.dart. I’m calling the interface.dart from the main.dart

I’m getting a permission denied error when try to access the contacts in the emulator

I added the permission_handler dependency in the pubspec.yaml
Then added the permissions in the AndroidManifest.xml for both read and write

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:contacts_service/contacts_service.dart';
import 'package:permission_handler/permission_handler.dart';
import 'dart:io';
import 'dart:convert';

import 'package:url_launcher/url_launcher.dart';
import 'package:path_provider/path_provider.dart';


class Interface extends StatelessWidget {
  const Interface({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('pAM'),
      ),
      body: const ContactSelector(),
    );
  }
}

class ContactSelector extends StatefulWidget {
  const ContactSelector({super.key});

  @override
  _ContactSelectorState createState() => _ContactSelectorState();
}

class _ContactSelectorState extends State<ContactSelector> {
  var status = Permission.contacts.status;

  Contact _selectedContact = Contact();
  late bool _isTrue;

  @override
  void initState() {
    super.initState();
    _readJson();
  }

  _selectContact() async {
    List<Contact> contact =
        await ContactsService.getContacts(withThumbnails: false);
    setState(() {
      _selectedContact = contact as Contact;
    });
    _saveContactToFile(_selectedContact);
  }

  _saveContactToFile(Contact contact) async {
    final directory = await getApplicationDocumentsDirectory();
    final file = File('${directory.path}/selected_contact.txt');
    if (!(await file.exists())) {
      file.create();
    }
    file.writeAsString(jsonEncode(contact.toMap()));
  }

  _readJson() async {
    final directory = await getApplicationDocumentsDirectory();
    final file = File('${directory.path}/true.json');
    if (!(await file.exists())) {
      file.createSync();
      file.writeAsStringSync('{"isTrue":true}');
    }
    final content = jsonDecode(await file.readAsString());
    setState(() {
      _isTrue = content['isTrue'];
    });
  }

  _promptMessage() {
    if (_isTrue) {
      showDialog(
        context: context,
        builder: (BuildContext context) {
          return AlertDialog(
            title: const Text('Select a message'),
            content: SingleChildScrollView(
              child: ListBody(
                children: <Widget>[
                  InkWell(
                      child: const Text('How are you?'),
                      onTap: () {
                        _sendMessage('How are you?');
                        Navigator.of(context).pop();
                      }),
                  InkWell(
                      child: const Text('Did you have your lunch ?'),
                      onTap: () {
                        _sendMessage('Did you have your lunch ?');
                        Navigator.of(context).pop();
                      }),
                  InkWell(
                      child: const Text("What's for dinner?"),
                      onTap: () {
                        _sendMessage("What's for dinner?");
                        Navigator.of(context).pop();
                      }),
                ],
              ),
            ),
          );
        },
      );
    }
  }

  String? encodeQueryParameters(Map<String, String> params) {
    return params.entries
        .map((e) =>
            '${Uri.encodeComponent(e.key)}=${Uri.encodeComponent(e.value)}')
        .join('&');
  }

  _sendMessage(String message) async {
    String phoneNumber = _selectedContact.phones.toString();
    Uri uri = Uri(
      scheme: 'sms',
      path: phoneNumber,
      query: encodeQueryParameters(<String, String>{
        'body': 'Welcome to pAM',
      }),
    );

    if (await canLaunchUrl(uri)) {
      await canLaunchUrl(uri);
    } else {
      throw 'Could not send SMS';
    }
  }

  @override
  Widget build(BuildContext context) {
    return MediaQuery(
        data: MediaQueryData.fromWindow(WidgetsBinding.instance.window),
        child: Scaffold(
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                if (_selectedContact != null)
                  Text(_selectedContact.displayName ?? 'No contact selected')
                else
                  const Text('No contact selected'),
                ElevatedButton(
                  onPressed: _selectContact,
                  child: const Text('Select Contact'),
                ),
                ElevatedButton(
                  onPressed: _promptMessage,
                  child: const Text('Prompt Message'),
                ),
              ],
            ),
          ),
        ));
  }
}

2

Answers


  1. You are facing this issues because you haven’t asked for the permission yet, refer the code below:

    import 'package:flutter/foundation.dart';
    import 'package:flutter/material.dart';
    import 'package:contacts_service/contacts_service.dart';
    import 'package:permission_handler/permission_handler.dart';
    import 'dart:io';
    import 'dart:convert';
    
    import 'package:url_launcher/url_launcher.dart';
    import 'package:path_provider/path_provider.dart';
    
    
    class Interface extends StatelessWidget {
      const Interface({super.key});
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text('pAM'),
          ),
          body: const ContactSelector(),
        );
      }
    }
    
    class ContactSelector extends StatefulWidget {
      const ContactSelector({super.key});
    
      @override
      _ContactSelectorState createState() => _ContactSelectorState();
    }
    
    class _ContactSelectorState extends State<ContactSelector> {
      var status = Permission.contacts.status;
    
      Contact _selectedContact = Contact();
      late bool _isTrue;
    
      @override
      void initState() {
        _readJson();
        super.initState();
        
      }
    
      _selectContact() async {
        if (await Permission.contacts.request().isGranted) {
               List<Contact> contact =
               await ContactsService.getContacts(withThumbnails: false);
              setState(() {
                 _selectedContact = contact as Contact;
               });
        _saveContactToFile(_selectedContact);
             }
      }
    
      _saveContactToFile(Contact contact) async {
        final directory = await getApplicationDocumentsDirectory();
        final file = File('${directory.path}/selected_contact.txt');
        if (!(await file.exists())) {
          file.create();
        }
        file.writeAsString(jsonEncode(contact.toMap()));
      }
    
      _readJson() async {
        final directory = await getApplicationDocumentsDirectory();
        final file = File('${directory.path}/true.json');
        if (!(await file.exists())) {
          file.createSync();
          file.writeAsStringSync('{"isTrue":true}');
        }
        final content = jsonDecode(await file.readAsString());
        setState(() {
          _isTrue = content['isTrue'];
        });
      }
    
      _promptMessage() {
        if (_isTrue) {
          showDialog(
            context: context,
            builder: (BuildContext context) {
              return AlertDialog(
                title: const Text('Select a message'),
                content: SingleChildScrollView(
                  child: ListBody(
                    children: <Widget>[
                      InkWell(
                          child: const Text('How are you?'),
                          onTap: () {
                            _sendMessage('How are you?');
                            Navigator.of(context).pop();
                          }),
                      InkWell(
                          child: const Text('Did you have your lunch ?'),
                          onTap: () {
                            _sendMessage('Did you have your lunch ?');
                            Navigator.of(context).pop();
                          }),
                      InkWell(
                          child: const Text("What's for dinner?"),
                          onTap: () {
                            _sendMessage("What's for dinner?");
                            Navigator.of(context).pop();
                          }),
                    ],
                  ),
                ),
              );
            },
          );
        }
      }
    
      String? encodeQueryParameters(Map<String, String> params) {
        return params.entries
            .map((e) =>
                '${Uri.encodeComponent(e.key)}=${Uri.encodeComponent(e.value)}')
            .join('&');
      }
    
      _sendMessage(String message) async {
        String phoneNumber = _selectedContact.phones.toString();
        Uri uri = Uri(
          scheme: 'sms',
          path: phoneNumber,
          query: encodeQueryParameters(<String, String>{
            'body': 'Welcome to pAM',
          }),
        );
    
        if (await canLaunchUrl(uri)) {
          await canLaunchUrl(uri);
        } else {
          throw 'Could not send SMS';
        }
      }
    
      @override
      Widget build(BuildContext context) {
        return MediaQuery(
            data: MediaQueryData.fromWindow(WidgetsBinding.instance.window),
            child: Scaffold(
              body: Center(
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    if (_selectedContact != null)
                      Text(_selectedContact.displayName ?? 'No contact selected')
                    else
                      const Text('No contact selected'),
                    ElevatedButton(
                      onPressed: _selectContact,
                      child: const Text('Select Contact'),
                    ),
                    ElevatedButton(
                      onPressed: _promptMessage,
                      child: const Text('Prompt Message'),
                    ),
                  ],
                ),
              ),
            ));
      }
    }
    
    Login or Signup to reply.
  2. Check the permission status first as this:-

     final status = Permission.contacts.request()
      
     if(status.isGrantet){
      // permission has granted now save the contact here
     }
    

    Refer this link for more details.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search