La plupart des applications de sauvegarde de contacts manquent d'une fonctionnalité ou d'une autre, par exemple elles ne sauvegardent pas les photos haute résolution lors de la création d'un fichier .vcf
. C'est pourquoi je préfère la méthode CLI pour extraire directement les données des contacts à partir du fichier de base de données en utilisant un script, mais cela nécessite des droits root. C'est ainsi que je sauvegarde mes contacts de manière planifiée sans compte Google.
Le script suivant ne sauvegarde pas les informations de compte de synchronisation Google dans le fichier .vcf
, mais vous pouvez étendre le script pour inclure/exclure des données si le concept est perçu.
Crédits originaux à dump-contacts2db.sh.
#!/system/bin/bash -e
# récupère les champs suivants des contacts de la base de données sqlite d'Android vers un vcf :
# Nom, Numéro de téléphone, E-mail, Adresse, Photo, Titre, Organisation, Notes, Site Web
# binaires requis : sqlite3, base64, xxd (tous inclus avec Android)
# répertoire des contacts, fichier de base de données et répertoire des photos
CONT_PROVIDER = '/data/user/0/com.android.providers.contacts'
DB = "$CONT_PROVIDER/databases/contacts2.db"
PHOTO_DIR = "$CONT_PROVIDER/files/photos"
# fichier vcf
VCF = "/data/media/0/contacts_$(date '+%d-%b-%y_%H-%M-%S').vcf"
# supprimer le fichier de sauvegarde en cas d'erreur
trap '[ $? -eq 0 ] || rm -f $VCF' EXIT
GEN_VCARD()
{
# sauter le contact vide la première fois
[ -n "$name" ] || return 0
# compter le nombre de contacts
n=$((n+1))
vcard = "${name}${tel}${adr}${email}${url}${note}${org}${title}${photo}"
vcard = "BEGIN:VCARD"$'\n'"VERSION:3.0"$'\n'"${vcard}""END:VCARD"
echo "$vcard" >>$VCF
echo >>$VCF
}
# récupérer les données des contacts à partir des différentes colonnes de la table 'view_entities' de la base de données sqlite des contacts
ROWS = "$(
sqlite3 $DB "
SELECT
view_entities._id, view_entities.mimetype_id, view_entities.data1, view_entities.data2, view_entities.data3,
view_entities.data4, view_entities.data5, view_entities.data6, quote(view_entities.data15), view_entities.photo_uri
FROM view_entities
WHERE view_entities.deleted = 0
ORDER BY view_entities._id, view_entities.mimetype_id
")"
# pour analyser les lignes
IFS = $'\n'
# parcourir les lignes de données des contacts
for ROW in $ROWS
do
# pour analyser les colonnes à partir d'une ligne
IFS = "|"
i = 0
# parcourir les colonnes
for COL in $ROW
do
i=$((i+1))
# données incluses dans chaque colonne
case $i in
1) # ID du contact
id = $COL ;;
2) # ID du type MIME
mime_id = $COL ;;
3) # Numéro de téléphone, Site Web, E-mail, Notes, Adresse, Organisation
data = $COL ;;
4) # ID du type de numéro de téléphone / E-mail / Adresse, Prénom
first_name = $COL ; type_id = $COL ;;
5) # Nom du type personnalisé de numéro de téléphone / Type d'E-mail / Type d'Adresse, Nom de famille
last_name = $COL ; type = $COL ;;
6) # Préfixe de nom, Titre
name_prefix = $COL ; tytle = $COL ;;
7) # Deuxième prénom
middle_name = $COL ;;
8) # Suffixe de nom
name_suffix = $COL ;;
9) # Données hexadécimales de la miniature de photo
photo_hex = $COL ;;
10) # URI de la photo en pleine résolution
photo_uri = $COL ;;
esac
done
# commencer un nouveau contact une fois que toutes les lignes du même ID de contact sont analysées
if [ "$prev_id" != "$id" ]
then
# echo vcard actuelle avant de réinitialiser les variables
GEN_VCARD
# initialiser une nouvelle vcard
for i in name tel adr email url note photo org title; do eval "$i = ''"; done
fi
# ajouter la ligne actuelle à la vcard actuelle, 'mime_type' détermine le type de données sur chaque ligne
case $mime_id in
1)
# E-mail
case $type_id in
0) email_type = X-$type ;;
1) email_type = DOMICILE ;;
2) email_type = TRAVAIL ;;
3) email_type = "" ;;
4) email_type = CELLULE ;;
*) echo "Type d'e-mail inconnu de '$data'" >&2; exit 1 ;;
esac
email = $email'EMAIL;TYPE='$email_type':'$data$'\n' ;;
4)
# Organisation, Titre
org = 'ORG:'$data$'\n'
title = 'TITLE:'$tytle$'\n' ;;
5)
# Numéro de téléphone
case $type_id in
0) tel_type = X-$type ;;
1) tel_type = DOMICILE ;;
2) tel_type = CELLULE ;;
3) tel_type = TRAVAIL ;;
7) tel_type = VOIX ;;
12) tel_type = PREF ;;
*) echo "Type de numéro de téléphone inconnu de '$data'" >&2; exit 1 ;;
esac
tel = $tel'TEL;TYPE='$tel_type':'$data$'\n' ;;
7)
# Nom
name = "$name_prefix $first_name $middle_name $last_name $name_suffix"
# supprimer les espaces en début/fin
IFS = ' ' read name <<<"$name"
# toujours ajouter le nom complet comme Prénom
name = "N:;"$name";;;"$'\n'"FN:"$name$'\n' ;;
8)
# Adresse postale
case $type_id in
0) adr_type = X-$type ;;
1) adr_type = DOMICILE ;;
2) adr_type = TRAVAIL ;;
*) echo "Type d'adresse inconnu de '$data'" >&2; exit 1 ;;
esac
adr = $adr'ADR;TYPE='$adr_type':;;'$data';;;;'$'\n' ;;
10)
# Photo
if [ $photo_hex != "NULL" ]
then
# rechercher une photo haute résolution au lieu de la miniature
uri = $(echo $photo_uri | sed 's|content://com.android.contacts/display_photo|'"$PHOTO_DIR"'|')
if [ -f $uri ]
then
# convertir en base64
foto = "$(base64 -w 0 $uri)"
else
# supprimer le préfixe/suffixe de la sortie hexadécimale, convertir l'hexadécimal en binaire en base64
foto = $(echo $photo_hex | sed "s/^X'// ; s/'$//" | tr '[:upper:]' '[:lower:]' | xxd -pr | base64 -w 0)
fi
photo = "PHOTO;ENCODING=BASE64;JPEG:"$foto$'\n'
fi ;;
12)
# Note
note = "NOTE:"$data$'\n' ;;
14)
# Site Web
url = $url"URL:"$data$'\n' ;;
*) echo "Type MIME inconnu : '$(sqlite3 $DB "SELECT view_entities.mimetype FROM view_entities WHERE view_entities.mimetype_id = $mime_id" | head -n1)" >&2 ; exit 1 ;;
esac
# conserver l'ID actuel pour comparer avec la ligne suivante
prev_id = $id
# réinitialiser IFS pour la boucle parentale pour analyser les lignes
IFS = $'\n'
done
# écho de la dernière vcard, la boucle est terminée
GEN_VCARD
echo "Sauvegardé $n contacts."
Si vous préférez une interface graphique ou si vous n'avez pas les droits root, vous pouvez utiliser une application comme Contacts VCF.