Display the app icon if the contact is associated

2019-01-07 21:29发布

问题:

I am trying to display the application icon for the phone number which is associated with the application.

I tried to follow this link but it is too difficult.
Is there any library for this or any easy way to solve this problem?

For example, we can say the contact is present in whatsapp, facebook, google, ... in phone address book.
Similarly I want to display my application icon beside these messenger applications.

回答1:

The following code shows a possible solution. Calling the synchronizeContact method will lead to adding the link in the contact app. Note it is not yet robust code but it shows the idea and is working. Note also the following two POJO classes are specific to my implementation and not essential to the working of the contact linking: PhoneNumber, ContactInfo.

MainActivity.java:

private void synchronizeContact(ContactInfo contactInfo)
{
    ContactsSyncAdapterService syncAdapter = new ContactsSyncAdapterService();
    Account account = new Account(contactInfo.getDisplayName(), getString(R.string.account_type)); //account_type = <yourpackage>.account
    PhoneNumber phoneNumber = contactInfo.getPhoneNumbers().get(0);
    syncAdapter.performSync(MainActivity.this, account, phoneNumber);
}

ContactsSyncAdapterService:

private static ContentResolver itsContentResolver = null;

public void performSync(Context context, Account account, PhoneNumber number)
{
    itsContentResolver = context.getContentResolver();
    addContact(account, account.name, account.name, number.getNumber());
}

private void addContact(Account account, String name, String username, String number)
{
    ArrayList<ContentProviderOperation> operationList = new ArrayList<ContentProviderOperation>();

    ContentProviderOperation.Builder builder = ContentProviderOperation.newInsert(RawContacts.CONTENT_URI);
    builder.withValue(RawContacts.ACCOUNT_NAME, account.name);
    builder.withValue(RawContacts.ACCOUNT_TYPE, account.type);
    builder.withValue(RawContacts.SYNC1, username);
    operationList.add(builder.build());

    builder = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI);
    builder.withValueBackReference(ContactsContract.CommonDataKinds.StructuredName.RAW_CONTACT_ID, 0);
    builder.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE);
    builder.withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, name);
    operationList.add(builder.build());

    builder = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI);
    builder.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0);
    builder.withValue(ContactsContract.Data.MIMETYPE, "vnd.android.cursor.item/vnd.<yourpackage>.profile");
    builder.withValue(ContactsContract.Data.DATA1, username);
    builder.withValue(ContactsContract.Data.DATA2, number);
    operationList.add(builder.build());

    try
    {
        itsContentResolver.applyBatch(ContactsContract.AUTHORITY, operationList);
    }
    catch (OperationApplicationException e)
    {
        e.printStackTrace();
    }
    catch (RemoteException e)
    {
        e.printStackTrace();
    }
}

ProfileActivity (class for the intent when tapping the contact app link):

@Override
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.profile);

    Uri intentData = getIntent().getData();
    if (isNotEmpty(intentData))
    {
        Cursor cursor = managedQuery(intentData, null, null, null, null);
        if (cursor.moveToNext())
        {
            String username = cursor.getString(cursor.getColumnIndex("DATA1"));
            String number = cursor.getString(cursor.getColumnIndex("DATA2"));
            TextView view = (TextView) findViewById(R.id.profiletext);
            view.setText("<yourtext>");
            doSomething(getPhoneNumber(number));
        }
    }
    else
    {
        handleIntentWithoutData();
    }
}

private void doSomething(PhoneNumber phoneNumber)
{
    Uri uri = Uri.parse("tel:" + phoneNumber.getNumber());
    Intent intent = new Intent(Intent.ACTION_CALL, uri);
    startActivity(intent);
}

contacts.xml:

<?xml version="1.0" encoding="utf-8"?>
<ContactsSource xmlns:android="http://schemas.android.com/apk/res/android">
    <ContactsDataKind
        android:icon="@drawable/ic_launcher"
        android:mimeType="vnd.android.cursor.item/vnd.<yourpackage>.profile"
        android:summaryColumn="data2"
        android:detailColumn="data3"
        android:detailSocialSummary="true"
    />

authenticator.xml:

<?xml version="1.0" encoding="utf-8"?>
<account-authenticator xmlns:android="http://schemas.android.com/apk/res/android"
    android:accountType="<yourpackage>.account"
    android:icon="@drawable/ic_launcher"
    android:smallIcon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:accountPreferences="@xml/account_preferences"
/>

account_preferences.xml:

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
</PreferenceScreen>

sync_contacts.xml:

<?xml version="1.0" encoding="utf-8"?>
<sync-adapter xmlns:android="http://schemas.android.com/apk/res/android"
    android:contentAuthority="com.android.contacts" 
    android:accountType="<yourpackage>.account"
    android:supportsUploading="false"
/>

PhoneNumber:

private String number;

public String getNumber()
{
    return number;
}

public void setNumber(String number)
{
    this.number = number;
}

ContactInfo:

private List<PhoneNumber> itsPhoneNumbers = new ArrayList<PhoneNumber>();

public void setDisplayName(String displayName)
{
    this.itsDisplayName = displayName;
}

public String getDisplayName()
{
    return itsDisplayName;
}

public void addPhoneNumber(PhoneNumber phoneNumber)
{
    this.itsPhoneNumbers.add(phoneNumber);
}

public List<PhoneNumber> getPhoneNumbers()
{
    return itsPhoneNumbers;
}