10
votes

Changer les contacts Image sur une grande photo avec ID de fichier photo dans Android

Cela semble fonctionner pour de petites images: xxx

du Docs Je me rends compte que pour les grandes images, je dois définir le photo_file_id, afin que je puisse remplacer: xxx

avec: xxx

Cependant, j'ai besoin de fournir un photo_file_id plutôt que des données brutes. Ma question:

  1. Comment puis-je enregistrer la photo (octet []) et obtenir une photo_file_id?
  2. S'il y a déjà une photo disponible (photo non photo_file_id). Dois-je le supprimer pour que la grosse image soit vue ou la grosse image prime-t-elle, sinon, comment la supprime-je?

0 commentaires

4 Réponses :


0
votes

Vous pouvez obtenir la photo de contact URI sans utiliser contactsContract.comMondatakinds.email.photo_uri de cette façon: Lire la réponse complète ici plus

Où! Pour obtenir le contact URI comme vous avez dit, essayez ceci: p> xxx pré>

Pour obtenir l'ID de contat à l'aide du numéro de téléphone Utilisez le code suivant: P>

import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.Phone;

public Uri getPhotoUri(long contactId) {
    ContentResolver contentResolver = getContentResolver();

    try {
        Cursor cursor = contentResolver
            .query(ContactsContract.Data.CONTENT_URI,
                null,
                ContactsContract.Data.CONTACT_ID
                    + "="
                    + contactId
                    + " AND "

                    + ContactsContract.Data.MIMETYPE
                    + "='"
                    + ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE
                    + "'", null, null);

        if (cursor != null) {
        if (!cursor.moveToFirst()) {
            return null; // no photo
        }
        } else {
        return null; // error in cursor process
        }

    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }

    Uri person = ContentUris.withAppendedId(
        ContactsContract.Contacts.CONTENT_URI, contactId);
    return Uri.withAppendedPath(person,
        ContactsContract.Contacts.Photo.CONTENT_DIRECTORY);
  }


1 commentaires

Je veux mettre la photo de contact URI



4
votes

a finalement été capable de le résoudre avec: xxx


0 commentaires

3
votes

Le photo_file_id est l'identifiant non d'un fichier (confusion) mais d'une ligne de la base de données contenant vos données photo brutes. Selon les documents que j'ai regardés, vous pouvez réellement éviter l'utilisation ( du docs ):

sous photo_file_id

Si présent, cela sera utilisé pour renseigner photo_uri

et sous photo_id ( qui est garantie rempli si photo_file_id existe )

référence à la ligne de la table de données contenant la photo. Une photo peut être appelée par ID (ce champ) ou par URI (voir photo_thumbnail_uri et photo_uri)

Cela implique que si vous utilisez simplement photo_uri , vous obtiendrez la même image résultante que si vous avez effectué la méthode OPENDISAYPHOTO . Il suggère également que les méthodes URI sont mieux compatibles avec les répertoires de 3ème pièce, de sorte que vous préférez travailler avec


3 commentaires

En fait, photo_file_id est l'ID (le nom du fichier, être plus précis) d'un fichier. C'est le nom de fichier de la photo comme stocké sous /data/data/com.android.providers.contacts/files/photos . Malheureusement, vous ne pouvez pas écrire des photos à l'aide de cet identifiant, vous ne pouvez les lire que.


Peut-être que cela n'était pas clair. Ce que je voulais dire, c'est que vous pouvez utiliser photo_uri avec lequel vous pouvez ouvrir un flux de sortie pour enregistrer vos nouvelles données et ne pas vous inquiéter de l'utilisation directe de l'ID. Les docs disent que photo_file_id est un entier, vous ne pouvez donc pas être le nom de fichier.


Vous ne pouvez pas écrire à un photo_uri . Ceci est seulement pour lire la photo principale du contact (agrégé). Ça ne fonctionne pas sur RawContacts Essayer d'écrire sur cette URI échouera (voir ContactsProvider2.java, ligne 8033 ). En ce qui concerne le nom de fichier, vous avez raison, le nom de fichier est la représentation décimale de la chaîne du photo_file_id . Mais à la fin, peu importe que ce n'est qu'un détail de mise en œuvre interne de toute façon.



20
votes

Votre propre réponse fonctionnera, mais ce n'est pas très efficace, car la photo doit être codée dans une requête SQL et de canaliser via Android IPC. Cela en fait également un sujet à la limite de taille IPC de 1 Mo d'Android (c'est-à-dire si votre photo est trop importante, l'opération de fournisseur de contenu échouera).

Le moyen le plus efficace de définir (créer ou remplacer) une photo de RawContact (primaire) est En utilisant OpenSetFileDedescriptor et un ContactContract.rawcontacts.displayPhoto Uri comme Donc (exemple copié de Android Docs): P>

public void writeDisplayPhoto(long rawContactId, byte[] photo) {
    Uri rawContactPhotoUri = Uri.withAppendedPath(
            ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
            RawContacts.DisplayPhoto.CONTENT_DIRECTORY);
    try {
        AssetFileDescriptor fd =
            getContentResolver().openAssetFileDescriptor(rawContactPhotoUri, "rw");
        OutputStream os = fd.createOutputStream();
        os.write(photo);
        os.close();
        fd.close();
    } catch (IOException e) {
        // Handle error cases.
    }
}


9 commentaires

@androidDeveloper Il n'y a pas de "meilleure façon qui fonctionnera toujours". Cela dépend de votre cas d'utilisation. Si vous mettez à jour l'image d'un contact existant, vous êtes probablement surtout le mieux avec cette méthode ( photo_file_id + OpenSetFileDedescriptor ). Parfois, il est préférable d'envoyer l'image dans un lot d'opérations de fournisseur de contenu. Par exemple, cela vous permet de créer un contact comprenant l'image dans une seule transaction. Nous utilisons cette méthode lorsque nous insérons de nouveaux contacts, mais nous préparons également des images pour s'assurer qu'ils ne soufflent pas des limites de l'IPC.


Je veux dire. Et si vous avez interrogé un contact (existant) et obtenu son identifiant de contact et sa clé de recherche. Maintenant, vous souhaitez ajouter / mettre à jour une photo à elle. Cette méthode fonctionnera-t-elle toujours (en supposant que vous obtenez un identifiant de contact brude)? Vous avez écrit que s'il a plusieurs photos, cela ne fonctionnera pas. Comment venir? Juste que j'ai demandé ici ici: Stackoverflow.com/q/45894991/878126 , et obtenu une réponse différente dans le code, et se demander s'il y a une meilleure façon.


Si vous avez l'ID de contact brude d'un contact existant, cette méthode créera / mettrea toujours à jour la photo principale (première) de ce contact cru. Si un contact cru a déjà plusieurs photos, seul le premier est mis à jour. Si le contact est lié à d'autres comptes, les photos des autres contacts bruts ne sont pas touchées. Donc, si la photo d'un autre contact RAW lié est la photo d'affichage super principale, l'utilisateur ne remarquera aucune différence. Si vous voulez vous assurer que l'utilisateur voit votre photo, vous devez en faire le super principal.


Est-il possible que je reçois tous les brouillards d'une personne, mais aucun d'entre eux ne permet de mettre à jour / insérer la photo? Si oui, ce qui devrait être fait dans ce cas?


Oui, c'est parfaitement possible. Imaginez simplement un compte Facebook et un compte WhatsApp sont liés sans un compte écritable. Dans ce cas, vous ne pouvez pas remplacer la photo de ce contact. La seule option serait d'ajouter un autre contact cru à votre propre type de compte, de le lier au contact existant (s'il n'est pas effectué automatiquement) et de faire sa photo la photo super principale. Selon votre cas d'utilisation, vous pourriez également être capable de résoudre celui-ci en ajoutant un contact cru local et non scindé. Vous devriez probablement commencer une autre question décrivant votre cas d'utilisation et le problème réel que vous rencontrez.


Comment puis-je ajouter "contact cru non synd"? En outre, j'ai créé cette question, ici: Stackoverflow.com/q/45894991/878126 , comme j'ai écrit ci-dessus ... :)


Les contacts bruts non mcs (aka contacts locaux) ont le type de compte null . J'ai lu votre question mais cela n'a pas vraiment indiqué que votre application fait. Il pourrait être préférable de mettre en œuvre votre propre type de compte. La création de contacts locaux ne devrait être que le dernier recours.


Je vois. Pouvez-vous me montrer comment créer une nouvelle donnée RawContact uniquement pour la photo, du stockage local, du contactID et de la liste de recherche?


Nous avons développé une bibliothèque appelée contentpal qui facilite la tâche de traiter avec ces opérations. Il y a quelques demandes de traction en attente dans notre repo qui devrait fournir à peu près tout ce dont vous avez besoin. Vous pouvez ouvrir un problème pour obtenir de l'aide là-bas. Je ne peux pas décrire cela dans un commentaire. Sachez également que chaque contact cru doit avoir au moins un nom.