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'),
),
],
),
),
));
}
}
CodePudding user response:
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'),
),
],
),
),
));
}
}
CodePudding user response:
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.