How to create and share the contact in flutter? - android

How to create the contact in locally with Name and phone number and share the created contact to other apps like whatsapp, social media's etc...
By using vcard_maintained library https://pub.dev/packages/vcard_maintained, we are able to create the contact, But not able to share through the apps.
I tried this,
import 'package:share_plus/share_plus.dart';
import 'package:vcard_maintained/vcard_maintained.dart';
var vCard = VCard();
vCard.firstName = 'FirstName';
vCard.middleName = 'MiddleName';
vCard.workPhone = '312-555-1212';
final path = await _localPath;
vCard.saveToFile('$path/contact.vcf');
Share.shareFiles(['$path/contact.vcf'], text: 'Great picture');
Future<String> get _localPath async {
final directory = await getApplicationDocumentsDirectory();
return directory.path;
}
But getting format of this vcard is not support error.

This is the working example.
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:path_provider/path_provider.dart';
import 'package:share_plus/share_plus.dart';
import 'package:vcard_maintained/vcard_maintained.dart';
void shareAllVCFCard(BuildContext context, {required List<VCard> vCard}) async {
try {
List<String> vcsCardPath = <String>[];
int index = 0;
for (final card in vCard) {
index++;
var vCardAsString = card.getFormattedString();
final directory = await getApplicationDocumentsDirectory();
final path = directory.path;
var pathAsText = "$path/$index.txt";
var contactAsFile = File(await getFilePath(index.toString()));
contactAsFile.writeAsString(vCardAsString);
var vcf = contactAsFile
.renameSync(contactAsFile.path.replaceAll(".txt", ".vcf"));
vcsCardPath.add(vcf.path);
}
Share.shareFiles(vcsCardPath, text: 'Great picture');
} catch (e) {
print("Error Creating VCF File $e");
return null;
}
}
Future<String> getFilePath(String fileName) async {
Directory appDocumentsDirectory =
await getApplicationDocumentsDirectory(); // 1
String appDocumentsPath = appDocumentsDirectory.path; // 2
String filePath = '$appDocumentsPath/$fileName.txt'; // 3
return filePath;
}

Related

how to pass xFile as a function parameter in flutter

I want to upload images to the server using flutter and HTTP package. I am able to display user-selected images but I want to upload them to the server but when I try to pass the image file to the function it gives me an error.
Image Picker Code :
XFile? uploadimage;
final ImagePicker _picker = ImagePicker();
Future<void> chooseImage() async {
var chooseImage = await _picker.pickImage(source: ImageSource.gallery);
setState(() {
uploadimage = chooseImage;
});
}
**services file code **
AdminSupervisorServices.createNewSupervisor(
_nameController.text,
_emailController.text,
_addressController.text,
_siteController.text,
_mobileController.text,
_passwordController.text,
uploadimage // error here
)
function body
static createNewSupervisor(String name, String email, String address,
String site, String mobileNumber, String password, File? image) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
List<int> imageBytes = image!.readAsBytesSync();
String baseimage = base64Encode(imageBytes);
var token = prefs.getString("token");
var response = await http
.post(Uri.parse("$baseURL/api/mmmmmmmm"), headers: {
'Authorization': 'Bearer $token',
}, body: {
"full_name": name,
"address": address,
"mobile_no": mobileNumber,
"email": email,
"site_name": site,
"password": password,
"image": baseimage,
});
print(response.body.toString());
var data = jsonDecode(response.body);
return data;
}
...
}
try this
if this work
import 'dart:io';
/////// Import for File
final File uploadimage = File("");
final ImagePicker _picker = ImagePicker();
Future<void> chooseImage() async {
var chooseImage = await _picker.pickImage(source: ImageSource.gallery);
setState(() {
uploadimage = File(chooseImage.path);
});
}
the function you have
AdminSupervisorServices.createNewSupervisor(
_nameController.text,
_emailController.text,
_addressController.text,
_siteController.text,
_mobileController.text,
_passwordController.text,
uploadimage
);
static createNewSupervisor(String name, String email, String address,
String site, String mobileNumber, String password, File? image)async{
...
}
Edit:
if you are passing image to a json
then you missing out is data:image/png;base64 something like this
lets assume this function return string.
///include import path
import 'package:path/path.dart' as path;
///////////////////////////////////////
imagetobase64(String? imagePath){
final extension = path.extension(imagePath
.substring(imagePath.lastIndexOf("/"))
.replaceAll("/", ""));
//// the extension return is png or jpg or jpeg which is needed
final bytes = File(imagePath).readAsBytesSync();
String base64 =
"data:image/${extension.replaceAll(".", "")};base64,${base64Encode(bytes)}";
return base64;
}
uploadimage is of type XFile? and you are passing it to a function which accepts parameter of File? type

"The return type 'String' isn't a 'bool', as required by the closure's context" when declaring a path to a pdf file

I am trying to make a listview of items that opens the designated PDF file in an asset folder upon being tapped
void openPDF(BuildContext context, File file) => Navigator.of(context).push(
MaterialPageRoute(builder: (context) => JournalViewerPage(file: file)),
);
onTap: ()async {
final path = 'assets/${journal_list.where((element) => element.fileLocation!)}';
final file = await JournalAPI.loadAsset(path);
openPDF(context, file);
},
However element.fileLocation is throwing an error stated in the title above. Here is the model to my listview
class JournalModel {
final String? journalTitle;
final int? journalReleaseYear;
final String? author;
final String? topic;
final String? fileLocation;
const JournalModel({
this.journalTitle,
this.journalReleaseYear,
this.author,
this.topic,
this.fileLocation,
});
}
And a few samples of the data i've inserted
import 'package:aplikasi_jurnal_mobile/models/journals.dart';
List<JournalModel> journal_list = [
const JournalModel(
journalTitle: 'Pembangunan Sistem Informasi Penjualan Obat Pada Apotek Punung',
journalReleaseYear: 2014,
author: "Tri Utami, Bambang Eka Purnama, Sukadi",
topic: "Medis",
fileLocation: '44-83-2-PB.pdf'
),
const JournalModel(
journalTitle: 'Pembuatan Aplikasi Pembelajaran Bahasa Inggris Pada Handphone dengan J2ME',
journalReleaseYear: 2010,
author: "Yusni Nyura",
topic: "Pendidikan",
fileLocation: '66-204-1-PB.pdf'
),
];
If it helps as well, here is the code to the API
import 'dart:async';
import 'package:flutter/services.dart';
import 'package:path_provider/path_provider.dart';
import 'package:aplikasi_jurnal_mobile/models/journals.dart';
import 'package:aplikasi_jurnal_mobile/data/journal_data.dart';
import 'dart:io';
import 'package:path/path.dart';
class JournalAPI {
static Future<File> loadAsset(String path) async{
final data = await rootBundle.load(path);
final bytes = data.buffer.asUint8List();
return _storeFile(path,bytes);
}
static Future<File> _storeFile(String path, List<int> bytes) async {
final filename = basename(path);
final dir = await getApplicationDocumentsDirectory();
final file = File('${dir.path}/$filename');
await file.writeAsBytes(bytes, flush: true);
return file;
}
}
I have tried changing fileLocation = 'assets/filename.pdf' to fileLocation = 'filename.pdf'and called it using final path =${journal_list.where((element) => element.fileLocation!)}, but no luck. I also tried changing JournalModel to const whereas previously it wasn't, still nothing.

Flutter - How to save audio as a file?

I am using :
flutter_sound_lite to record some audio.
and path_provider to get path of my phone.
permission_handler
I am creating directories and a file with a specified path to put my recorded audio.
I wonder if i am not finding it or it doesn't get created.
import 'dart:io';
import 'dart:typed_data';
import 'package:flutter_sound_lite/flutter_sound.dart';
import 'package:flutter_sound_lite/public/flutter_sound_recorder.dart';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';
class SoundRecorder {
FlutterSoundRecorder? _audioRecorder;
ModelApiShazam? modelApiShazam;
bool _isRecorderInitialised = false;
bool get isRecording => _audioRecorder!.isRecording;
Future init() async {
_audioRecorder = FlutterSoundRecorder();
final statusMic = await Permission.microphone.request();
if(statusMic != PermissionStatus.granted){
throw RecordingPermissionException('microphone permission');
}
final statusStorage = await Permission.storage.status;
if (!statusStorage.isGranted) {
await Permission.storage.request();
}
await _audioRecorder!.openAudioSession();
directoryPath = await _directoryPath();
completePath = await _completePath(directoryPath);
_createDirectory();
_createFile();
_isRecorderInitialised = true;
}
void dispose(){
if(!_isRecorderInitialised) return;
_audioRecorder!.closeAudioSession();
_audioRecorder = null;
_isRecorderInitialised = false;
}
Future _record() async{
if(!_isRecorderInitialised) return;
print("Path where the file will be : "+completePath);
await _audioRecorder!.startRecorder(
toFile: completePath,
numChannels : 1,
sampleRate: 44100,
);
}
Future _stop() async{
if(!_isRecorderInitialised) return;
var s = await _audioRecorder!.stopRecorder();
File f = File(completePath);
print("The created file : $f");
}
Future toggleRecording() async{
if(_audioRecorder!.isStopped){
await _record();
}else{
await _stop();
}
}
String completePath = "";
String directoryPath = "";
Future<String> _completePath(String directory) async {
var fileName = _fileName();
return "$directory$fileName";
}
Future<String> _directoryPath() async {
var directory = await getApplicationDocumentsDirectory();
var directoryPath = directory.path;
return "$directoryPath/records/";
}
String _fileName() {
return "record.wav";
}
Future _createFile() async {
File(completePath)
.create(recursive: true)
.then((File file) async {
//write to file
Uint8List bytes = await file.readAsBytes();
file.writeAsBytes(bytes);
print("FILE CREATED AT : "+file.path);
});
}
void _createDirectory() async {
bool isDirectoryCreated = await Directory(directoryPath).exists();
if (!isDirectoryCreated) {
Directory(directoryPath).create()
.then((Directory directory) {
print("DIRECTORY CREATED AT : " +directory.path);
});
}
}
}
output excluding flutter_sound :
I/flutter (20652): DIRECTORY CREATED AT : /data/user/0/com.example.shazam/app_flutter/records/
I/flutter (20652): FILE CREATED AT : /data/user/0/com.example.shazam/app_flutter/records/record.wav
I press the button to start the record...
I/flutter (20652): Path where the file will be : /data/user/0/com.example.shazam/app_flutter/records/record.wav
I press the button to end the record...
I/flutter (20652): The created file : File: '/data/user/0/com.example.shazam/app_flutter/records/record.wav'
I don't find where this file is located even if i am following the path
I founs the solution !
Just replace
var directory = await getApplicationDocumentsDirectory();
var directoryPath = directory.path;
by
var directory = await getExternalStorageDirectory();
var directoryPath = directory!.path;

Flutter Error: _TypeError (type 'Null' is not a subtype of type 'FutureOr<Database>')

Opening the sqlite database in assets folder. but I get this error.
I tried ' return _db ?? = await initDb(); ' but it's not work.
i don't understand why i got this error..
please help me..
import 'dart:async';
import 'dart:io';
import 'dart:typed_data';
import 'package:bankingapp/models/histories.dart';
import 'package:flutter/services.dart';
import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';
class DbHelper {
static Database? _db;
Future<Database> get db async {
return _db = await initDb(); // <-- error is here
}
initDb() async {
var dbDir = await getDatabasesPath();
var dbPath = join(dbDir, "app.db");
// Delete any existing database:
await deleteDatabase(dbPath);
// Create the writable database file from the bundled demo database file:
ByteData data = await rootBundle.load("assets/database/bankingapp.db");
List<int> bytes =
data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
await File(dbPath).writeAsBytes(bytes);
var db = await openDatabase(dbPath);
/*
var dbFolder = await getDatabasesPath();
String path = join(dbFolder, 'app.db');
return await openDatabase(path);*/
}
Future<List<Histories>> getHistories() async {
var dbClient = await db;
var result = await dbClient.rawQuery("SELECT * FROM Histories");
return result.map((data) => Histories.fromMap(data)).toList();
}
}
This code will help you.
Future<Database> initDb() async {
var dbFolder = await getDatabasesPath();
String path = join(dbFolder, 'app.db');
// Delete any existing database:
await deleteDatabase(path);
// Create the writable database file from the bundled demo database file:
try {
await Directory(dirname(path)).create(recursive: true);
} catch (_) {}
ByteData data =
await rootBundle.load(join("assets/database", "bankingapp.db"));
List<int> bytes =
data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
await new File(path).writeAsBytes(bytes, flush: true);
//open the database
return await openDatabase(path);
}

Flutter : Create directory on external storage path - path provider getExternalStorageDirectory()

I'm creating a flutter app where I want to download and store an image to the external storage (not documents directory) so it can be viewed by any photo gallery app.
I'm using the following code to create a directory
var dir = await getExternalStorageDirectory();
if(!Directory("${dir.path}/myapp").existsSync()){
Directory("${dir.path}/myapp").createSync(recursive: true);
}
It's giving me following error:
FileSystemException: Creation failed, path = '/storage/emulated/0/myapp' (OS Error: Permission denied, errno = 13)
I have set up permissions in the manifest file and using the following code for runtime permissions
List<Permissions> permissions = await Permission.getPermissionStatus([PermissionName.Storage]);
permissions.forEach((p) async {
if(p.permissionStatus != PermissionStatus.allow){
final res = await Permission.requestSinglePermission(PermissionName.Storage);
print(res);
}
});
I have verified in settings that app has got the permission, also as suggested on some answers here I've also tried giving permission from settings app manually which did not work.
You need to request permissions before saving a file using getExternalStorageDirectory.
Add this to Androidmanifest.xml:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Then use the permission_handler package to get Storage permission:
https://pub.dev/packages/permission_handler
If you are running in the Emulator, getExternalStorageDirectory returns:
/storage/emulated/0/Android/data/com.example.myapp/files/
If you just need the external dir to create a directory under it, then just use:
/storage/emulated/0/
You can create a directory under this folder, so they user will be able to open the files.
The below code is working fine in my application to download an image using the url to the external storage
Future<bool> downloadImage(String url) async {
await new Future.delayed(new Duration(seconds: 1));
bool checkResult =
await SimplePermissions.checkPermission(Permission.WriteExternalStorage);
if (!checkResult) {
var status = await SimplePermissions.requestPermission(
Permission.WriteExternalStorage);
if (status == PermissionStatus.authorized) {
var res = await saveImage(url);
return res != null;
}
} else {
var res = await saveImage(url);
return res != null;
}
return false;
}
Future<Io.File> saveImage(String url) async {
try {
final file = await getImageFromNetwork(url);
var dir = await getExternalStorageDirectory();
var testdir =
await new Io.Directory('${dir.path}/iLearn').create(recursive: true);
IM.Image image = IM.decodeImage(file.readAsBytesSync());
return new Io.File(
'${testdir.path}/${DateTime.now().toUtc().toIso8601String()}.png')
..writeAsBytesSync(IM.encodePng(image));
} catch (e) {
print(e);
return null;
}
}
Future<Io.File> getImageFromNetwork(String url) async {
var cacheManager = await CacheManager.getInstance();
Io.File file = await cacheManager.getFile(url);
return file;
}
Namespaces
import 'dart:io' as Io;
import 'package:image/image.dart' as IM;
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
import 'package:path_provider/path_provider.dart';
import 'package:simple_permissions/simple_permissions.dart';
Hope it helps
here is an operational and 100% Dart code to make things easier :
import 'dart:async';
import 'dart:developer';
import 'dart:io';
import 'package:path/path.dart' as Path;
import 'package:path_provider/path_provider.dart';
///getExternalStoragePublicDirectory
enum extPublicDir {
Music,
PodCasts,
Ringtones,
Alarms,
Notifications,
Pictures,
Movies,
Download,
DCIM,
Documents,
Screenshots,
Audiobooks,
}
/// use in loop or without:
/// generation loop of a creation of the same directory in a list
/// public or shared folders by the Android system
/*
for (var ext in extPublicDir.values) {
ExtStorage.createFolderInPublicDir(
type: ext, //or without loop : extPublicDir.Download,
folderName: "folderName", // folder or folder/subFolder/... to create
);
}
*/
/// provided the ability to create folders and files within folders
/// public or shared from the Android system
///
/// /storage/emulated/0/Audiobooks
/// /storage/emulated/0/PodCasts
/// /storage/emulated/0/Ringtones
/// /storage/emulated/0/Alarms
/// /storage/emulated/0/Notifications
/// /storage/emulated/0/Pictures
/// /storage/emulated/0/Movies
/// storage/emulated/0/Download
/// /storage/emulated/0/DCIM
/// /storage/emulated/0/Documents
/// /storage/emulated/0/Screenshots //Screenshots dropping ?
/// /storage/emulated/0/Music/
class ExtStorage {
//According to path_provider
static Future<String> get _directoryPathESD async {
var directory = await getExternalStorageDirectory();
if (directory != null) {
log('directory:${directory.path}');
return directory.path;
}
log('_directoryPathESD==null');
return '';
}
/// create or not, but above all returns the created folder in a public folder
/// official, folderName = '', only return the public folder: useful for
/// manage a file at its root
static Future<String> createFolderInPublicDir({
required extPublicDir type,
required String folderName,
}) async {
var _appDocDir = await _directoryPathESD;
log("createFolderInPublicDir:_appDocDir:${_appDocDir.toString()}");
var values = _appDocDir.split("${Platform.pathSeparator}");
values.forEach(print);
var dim = values.length - 4; // Android/Data/package.name/files
_appDocDir = "";
for (var i = 0; i < dim; i++) {
_appDocDir += values[i];
_appDocDir += "${Platform.pathSeparator}";
}
_appDocDir += "${type.toString().split('.').last}${Platform.pathSeparator}";
_appDocDir += folderName;
log("createFolderInPublicDir:_appDocDir:$_appDocDir");
if (await Directory(_appDocDir).exists()) {
log("createFolderInPublicDir:reTaken:$_appDocDir");
return _appDocDir;
} else {
log("createFolderInPublicDir:toCreate:$_appDocDir");
//if folder not exists create folder and then return its path
final _appDocDirNewFolder =
await Directory(_appDocDir).create(recursive: true);
final pathNorma = Path.normalize(_appDocDirNewFolder.path);
log("createFolderInPublicDir:ToCreate:pathNorma:$pathNorma");
return pathNorma;
}
}
}
For Android 11 and higher, android change his policy so you have add permission at AndroidManifest..
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
And Also add these two line inside <application ......
android:requestLegacyExternalStorage="true"
android:preserveLegacyExternalStorage="true"

Categories

Resources