mirror of
https://github.com/oxen-io/session-android.git
synced 2025-12-03 05:22:23 +00:00
Added ability to share contacts.
The "contact" option in the attachments tray now brings you through an optimized contact sharing flow, allowing you to select specific fields to share. The contact is then presented as a special message type, allowing you to interact with the card to add the contact to your system contacts, invite them to signal, initiate a signal message, etc.
This commit is contained in:
@@ -19,6 +19,8 @@ package org.thoughtcrime.securesms.contacts;
|
||||
import android.accounts.Account;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.ContentProviderOperation;
|
||||
import android.content.ContentProviderResult;
|
||||
import android.content.ContentUris;
|
||||
import android.content.Context;
|
||||
import android.content.OperationApplicationException;
|
||||
import android.database.Cursor;
|
||||
@@ -226,6 +228,114 @@ public class ContactsDatabase {
|
||||
|
||||
}
|
||||
|
||||
public @Nullable Cursor getNameDetails(long contactId) {
|
||||
String[] projection = new String[] { ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME,
|
||||
ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME,
|
||||
ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME,
|
||||
ContactsContract.CommonDataKinds.StructuredName.PREFIX,
|
||||
ContactsContract.CommonDataKinds.StructuredName.SUFFIX,
|
||||
ContactsContract.CommonDataKinds.StructuredName.MIDDLE_NAME };
|
||||
String selection = ContactsContract.Data.CONTACT_ID + " = ? AND " + ContactsContract.Data.MIMETYPE + " = ?";
|
||||
String[] args = new String[] { String.valueOf(contactId), ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE };
|
||||
|
||||
return context.getContentResolver().query(ContactsContract.Data.CONTENT_URI,
|
||||
projection,
|
||||
selection,
|
||||
args,
|
||||
null);
|
||||
}
|
||||
|
||||
public @Nullable String getOrganizationName(long contactId) {
|
||||
String[] projection = new String[] { ContactsContract.CommonDataKinds.Organization.COMPANY };
|
||||
String selection = ContactsContract.Data.CONTACT_ID + " = ? AND " + ContactsContract.Data.MIMETYPE + " = ?";
|
||||
String[] args = new String[] { String.valueOf(contactId), ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE };
|
||||
|
||||
try (Cursor cursor = context.getContentResolver().query(ContactsContract.Data.CONTENT_URI,
|
||||
projection,
|
||||
selection,
|
||||
args,
|
||||
null))
|
||||
{
|
||||
if (cursor != null && cursor.moveToFirst()) {
|
||||
return cursor.getString(0);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public @Nullable Cursor getPhoneDetails(long contactId) {
|
||||
String[] projection = new String[] { ContactsContract.CommonDataKinds.Phone.NUMBER,
|
||||
ContactsContract.CommonDataKinds.Phone.TYPE,
|
||||
ContactsContract.CommonDataKinds.Phone.LABEL };
|
||||
String selection = ContactsContract.Data.CONTACT_ID + " = ? AND " + ContactsContract.Data.MIMETYPE + " = ?";
|
||||
String[] args = new String[] { String.valueOf(contactId), ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE };
|
||||
|
||||
return context.getContentResolver().query(ContactsContract.Data.CONTENT_URI,
|
||||
projection,
|
||||
selection,
|
||||
args,
|
||||
null);
|
||||
}
|
||||
|
||||
public @Nullable Cursor getEmailDetails(long contactId) {
|
||||
String[] projection = new String[] { ContactsContract.CommonDataKinds.Email.ADDRESS,
|
||||
ContactsContract.CommonDataKinds.Email.TYPE,
|
||||
ContactsContract.CommonDataKinds.Email.LABEL };
|
||||
String selection = ContactsContract.Data.CONTACT_ID + " = ? AND " + ContactsContract.Data.MIMETYPE + " = ?";
|
||||
String[] args = new String[] { String.valueOf(contactId), ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE };
|
||||
|
||||
return context.getContentResolver().query(ContactsContract.Data.CONTENT_URI,
|
||||
projection,
|
||||
selection,
|
||||
args,
|
||||
null);
|
||||
}
|
||||
|
||||
public @Nullable Cursor getPostalAddressDetails(long contactId) {
|
||||
String[] projection = new String[] { ContactsContract.CommonDataKinds.StructuredPostal.TYPE,
|
||||
ContactsContract.CommonDataKinds.StructuredPostal.LABEL,
|
||||
ContactsContract.CommonDataKinds.StructuredPostal.STREET,
|
||||
ContactsContract.CommonDataKinds.StructuredPostal.POBOX,
|
||||
ContactsContract.CommonDataKinds.StructuredPostal.NEIGHBORHOOD,
|
||||
ContactsContract.CommonDataKinds.StructuredPostal.CITY,
|
||||
ContactsContract.CommonDataKinds.StructuredPostal.REGION,
|
||||
ContactsContract.CommonDataKinds.StructuredPostal.POSTCODE,
|
||||
ContactsContract.CommonDataKinds.StructuredPostal.COUNTRY };
|
||||
String selection = ContactsContract.Data.CONTACT_ID + " = ? AND " + ContactsContract.Data.MIMETYPE + " = ?";
|
||||
String[] args = new String[] { String.valueOf(contactId), ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE };
|
||||
|
||||
return context.getContentResolver().query(ContactsContract.Data.CONTENT_URI,
|
||||
projection,
|
||||
selection,
|
||||
args,
|
||||
null);
|
||||
}
|
||||
|
||||
public @Nullable Uri getAvatarUri(long contactId) {
|
||||
String[] projection = new String[] { ContactsContract.CommonDataKinds.Photo.PHOTO_URI };
|
||||
String selection = ContactsContract.Data.CONTACT_ID + " = ? AND " + ContactsContract.Data.MIMETYPE + " = ?";
|
||||
String[] args = new String[] { String.valueOf(contactId), ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE };
|
||||
|
||||
try (Cursor cursor = context.getContentResolver().query(ContactsContract.Data.CONTENT_URI,
|
||||
projection,
|
||||
selection,
|
||||
args,
|
||||
null))
|
||||
{
|
||||
if (cursor != null && cursor.moveToFirst()) {
|
||||
String uri = cursor.getString(0);
|
||||
if (uri != null) {
|
||||
return Uri.parse(uri);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void addContactVoiceSupport(List<ContentProviderOperation> operations,
|
||||
@NonNull Address address, long rawContactId)
|
||||
{
|
||||
|
||||
@@ -2,6 +2,9 @@ package org.thoughtcrime.securesms.contacts.avatars;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
|
||||
import com.bumptech.glide.load.Key;
|
||||
@@ -13,4 +16,8 @@ public interface ContactPhoto extends Key {
|
||||
|
||||
InputStream openInputStream(Context context) throws IOException;
|
||||
|
||||
@Nullable Uri getUri(@NonNull Context context);
|
||||
|
||||
boolean isProfilePhoto();
|
||||
|
||||
}
|
||||
|
||||
@@ -2,7 +2,9 @@ package org.thoughtcrime.securesms.contacts.avatars;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import org.thoughtcrime.securesms.database.Address;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
@@ -37,6 +39,16 @@ public class GroupRecordContactPhoto implements ContactPhoto {
|
||||
throw new IOException("Couldn't load avatar for group: " + address.toGroupString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Uri getUri(@NonNull Context context) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isProfilePhoto() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDiskCacheKey(MessageDigest messageDigest) {
|
||||
messageDigest.update(address.serialize().getBytes());
|
||||
|
||||
@@ -2,7 +2,9 @@ package org.thoughtcrime.securesms.contacts.avatars;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import org.thoughtcrime.securesms.database.Address;
|
||||
import org.thoughtcrime.securesms.profiles.AvatarHelper;
|
||||
@@ -27,6 +29,16 @@ public class ProfileContactPhoto implements ContactPhoto {
|
||||
return AvatarHelper.getInputStreamFor(context, address);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Uri getUri(@NonNull Context context) {
|
||||
return Uri.fromFile(AvatarHelper.getAvatarFile(context, address));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isProfilePhoto() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDiskCacheKey(MessageDigest messageDigest) {
|
||||
messageDigest.update(address.serialize().getBytes());
|
||||
|
||||
@@ -4,6 +4,7 @@ package org.thoughtcrime.securesms.contacts.avatars;
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import org.thoughtcrime.securesms.database.Address;
|
||||
import org.thoughtcrime.securesms.util.Conversions;
|
||||
@@ -27,7 +28,17 @@ public class SystemContactPhoto implements ContactPhoto {
|
||||
@Override
|
||||
public InputStream openInputStream(Context context) throws FileNotFoundException {
|
||||
return context.getContentResolver().openInputStream(contactPhotoUri);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Uri getUri(@NonNull Context context) {
|
||||
return contactPhotoUri;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isProfilePhoto() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user