La mayoría de las aplicaciones de copia de seguridad de los contactos carecen de una u otra característica, por ejemplo, no hacen una copia de seguridad de las fotos de alta resolución al crear .vcf
archivo. Así que prefiero el método CLI para extraer los datos de los contactos directamente del archivo de la base de datos utilizando algún script, pero se necesita root . Así es como hago la copia de seguridad programada de mis contactos sin cuenta de Google.
El siguiente script no guarda la información de la cuenta de Google sync en .vcf
pero se puede extender el script para incluir/excluir cualquier dato si se percibe el concepto.
Créditos originales a dump-contacts2db.sh .
#!/system/bin/bash -e
# dumps following fields of contacts from Android's sqlite database to vcf:
# Name, Phone Number, Email, Address, Photo, Title, Organization, Notes, Website
# required binaries: sqlite3, base64, xxd (all included with Android)
# contacts directory, database file and photos directory
CONT_PROVIDER='/data/user/0/com.android.providers.contacts'
DB="$CONT_PROVIDER/databases/contacts2.db"
PHOTO_DIR="$CONT_PROVIDER/files/photos"
# vcf file
VCF="/data/media/0/contacts_$(date '+%d-%b-%y_%H-%M-%S').vcf"
# delete backup file if error occurs
trap '[ $? -eq 0 ] || rm -f $VCF' EXIT
GEN_VCARD()
{
# skip blank contact for first time
[ -n "$name" ] || return 0
# count number of 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
}
# fetch contacts data from different columns of 'view_entities' table of contacts sqlite database
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
")"
# to parse rows
IFS=$'\n'
# iterate through contacts data rows
for ROW in $ROWS
do
# to parse columns from a row
IFS="|"
i=0
# iterate through columns
for COL in $ROW
do
i=$((i+1))
# data included in each column
case $i in
1) # Contact ID
id=$COL;;
2) # Mime Type ID
mime_id=$COL;;
3) # Phone Number, Website, Email, Notes, Address, Organization
data=$COL;;
4) # Type ID of Phone No. / Email / Address, First Name
first_name=$COL; type_id=$COL;;
5) # Name of Custom Phone No. Type / Email Type / Address Type, Last Name
last_name=$COL; type=$COL;;
6) # Name Prefix, Title
name_prefix=$COL; tytle=$COL;;
7) # Middle Name
middle_name=$COL;;
8) # Name Suffix
name_suffix=$COL;;
9) # Photo thumbnail hex data
photo_hex=$COL;;
10) # Full resolution Photo URI
photo_uri=$COL;;
esac
done
# start new contact when all rows of same contact ID are parsed
if [ "$prev_id" != "$id" ]
then
# echo current vcard prior to resetting variables
GEN_VCARD
# init new vcard
for i in name tel adr email url note photo org title; do eval "$i=''"; done
fi
# add current row to current vcard, 'mimetype' determines data type on every row
case $mime_id in
1)
# Email
case $type_id in
0) email_type=X-$type;;
1) email_type=HOME;;
2) email_type=WORK;;
3) email_type="";;
4) email_type=CELL;;
*) echo "Unknown email type of '$data'" >&2; exit 1;;
esac
email=$email'EMAIL;TYPE='$email_type':'$data$'\n';;
4)
# Organization, Title
org='ORG:'$data$'\n'
title='TITLE:'$tytle$'\n';;
5)
# Phone No.
case $type_id in
0) tel_type=X-$type;;
1) tel_type=HOME;;
2) tel_type=CELL;;
3) tel_type=WORK;;
7) tel_type=VOICE;;
12) tel_type=PREF;;
*) echo "Unknown phone no. type of '$data'" >&2; exit 1;;
esac
tel=$tel'TEL;TYPE='$tel_type':'$data$'\n';;
7)
# Name
name="$name_prefix $first_name $middle_name $last_name $name_suffix"
# remove leading/trailing spaces
IFS=' ' read name <<<"$name"
# always add complete name as First Name
name="N:;"$name";;;"$'\n'"FN:"$name$'\n';;
8)
# Postal Address
case $type_id in
0) adr_type=X-$type;;
1) adr_type=HOME;;
2) adr_type=WORK;;
*) echo "Unknown address type of '$data'" >&2; exit 1;;
esac
adr=$adr'ADR;TYPE='$adr_type':;;'$data';;;;'$'\n';;
10)
# Photo
if [ $photo_hex != "NULL" ]
then
# look for high-resolution photo instead of thumbnail
uri=$(echo $photo_uri | sed 's|content://com.android.contacts/display_photo|'"$PHOTO_DIR"'|')
if [ -f $uri ]
then
# convert binary to base64
foto="$(base64 -w 0 $uri)"
else
# remove prefix/suffix from hex output, convert hex to binary to 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)
# Website
url=$url"URL:"$data$'\n';;
*) echo "Unknown mime type: '$(sqlite3 $DB "SELECT view_entities.mimetype FROM view_entities WHERE view_entities.mimetype_id = $mime_id" | head -n1)'" >&2; exit 1;;
esac
# preserve current ID to compare with next row
prev_id=$id
# reset IFS for parent loop to parse rows
IFS=$'\n'
done
# echo last vcard, loop is done
GEN_VCARD
echo "Backed up $n contacts."
Si prefieres la GUI o no tienes Root, puedes usar alguna aplicación como Contactos VCF .