4

Background

I've found that there is a way to open a specific contact conversation screen on WhatsApp, here .

Not only that, but I've found that an app called "Drupe" does the same, and maybe even more :

https://lh3.googleusercontent.com/EQrs1jplMlP8SkOTdpqT4NzmgzGa5Wz2qageG1Pkjc6rKg0HBb-rwlOVW07_G7bAWgo=h900

The problem

I can't find any official API of opening it this way, so I'm not sure how safe it is.

I've found SDKs, but not intents instructions.

The questions

I'd like to know more about what's available for various social-networks and chatting apps :

  • WhatsApp
  • Facebook Messenger
  • Viber
  • Line
  • Telegram
  • Hangouts

Possible features may be:

  • open the conversation of a contact, when input is his phone number
  • have a new text that will be ready to be sent in the new screen
  • for Facebook, maybe also be able to open using the Facebook-ID of the person (meaning this is the input), instead of a phone number.

Are such features available for each of those social networks and chatting apps?

Community
  • 1
  • 1
android developer
  • 114,585
  • 152
  • 739
  • 1,270

3 Answers3

22

For Facebook-messenger, I've found this (from https://developers.facebook.com/docs/messenger-platform/discovery/m-me-links#format):

final Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://m.me/" + facebookId));

It works, but I wonder if there is another way to access it (using phone number, for example).


For WhatsApp, I've found this (from here) :

    final String formattedPhoneNumber = getFormattedPhoneNumber(this, phone);
    final String contactId = getContactIdFromPhoneNumber(phone);
    final String contactMimeTypeDataId = getContactMimeTypeDataId(contactId, "vnd.android.cursor.item/vnd.com.whatsapp.profile");
    if (contactMimeTypeDataId != null) {
        intent = new Intent(Intent.ACTION_SENDTO, Uri.parse("smsto:" + formattedPhoneNumber));
        intent.setPackage("com.whatsapp");
    } else
        Toast.makeText(this, "cannot find this contact on whatsapp", Toast.LENGTH_SHORT).show();

public static String getFormattedPhoneNumber(Context context, String input) {
    final PhoneNumberUtil phoneNumberUtil = PhoneNumberUtil.getInstance();
    String normalizedPhone = input.replaceAll("[^0-9+]", "");
    try {
        TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        String countryCode = tm.getSimCountryIso();
        final PhoneNumber phoneNumber = phoneNumberUtil.parse(normalizedPhone, countryCode.toUpperCase());
        final String formattedPhoneNumber = phoneNumberUtil.format(phoneNumber, PhoneNumberFormat.E164).replaceAll("[^0-9]", "");
        return formattedPhoneNumber;
    } catch (NumberParseException e) {
        e.printStackTrace();
    }
    return null;
}

private String getContactIdFromPhoneNumber(String phone) {
    if (TextUtils.isEmpty(phone))
        return null;
    final Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phone));
    final ContentResolver contentResolver = getContentResolver();
    final Cursor phoneQueryCursor = contentResolver.query(uri, new String[]{PhoneLookup._ID}, null, null, null);
    if (phoneQueryCursor != null) {
        if (phoneQueryCursor.moveToFirst()) {
            String result = phoneQueryCursor.getString(phoneQueryCursor.getColumnIndex(PhoneLookup._ID));
            phoneQueryCursor.close();
            return result;
        }
        phoneQueryCursor.close();
    }
    return null;
}

public String getContactMimeTypeDataId(@NonNull Context context, String contactId, @NonNull String mimeType) {
    if (TextUtils.isEmpty(mimeType))
        return null;
    ContentResolver cr = context.getContentResolver();
    Cursor cursor = cr.query(ContactsContract.Data.CONTENT_URI, new String[]{Data._ID}, Data.MIMETYPE + "= ? AND "
            + ContactsContract.Data.CONTACT_ID + "= ?", new String[]{mimeType, contactId}, null);
    if (cursor == null)
        return null;
    if (!cursor.moveToFirst()) {
        cursor.close();
        return null;
    }
    String result = cursor.getString(cursor.getColumnIndex(Data._ID));
    cursor.close();
    return result;
}

It works, but it doesn't add the message. It also might say the contact doesn't have WhatsApp.

It's also possible to just use the phone number, as I wrote here.


For Viber, I've found this (from here) :

        final String contactId = getContactIdFromPhoneNumber(phone);
        final String contactMimeTypeDataId = getContactMimeTypeDataId(contactId, "vnd.android.cursor.item/vnd.com.viber.voip.viber_number_message");
        if (contactMimeTypeDataId != null) {
            intent = new Intent(Intent.ACTION_VIEW, Uri.parse("content://com.android.contacts/data/" + contactMimeTypeDataId));
            intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT | Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET | Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP);
            intent.setPackage("com.viber.voip");
        } else {
            intent = new Intent("android.intent.action.VIEW", Uri.parse("tel:" + Uri.encode(formattedPhoneNumber)));
            intent.setClassName("com.viber.voip", "com.viber.voip.WelcomeActivity");
        }

private String getContactIdFromPhoneNumber(String phone) {
    final Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phone));
    final ContentResolver contentResolver = getContentResolver();
    final Cursor phoneQueryCursor = contentResolver.query(uri, new String[]{PhoneLookup._ID}, null, null, null);
    if (phoneQueryCursor != null) {
        if (phoneQueryCursor.moveToFirst()) {
            String result = phoneQueryCursor.getString(phoneQueryCursor.getColumnIndex(PhoneLookup._ID));
            phoneQueryCursor.close();
            return result;
        }
        phoneQueryCursor.close();
    }
    return null;
}

For Hangouts, it seems it's similar to Viber, but with this mimetype: "vnd.android.cursor.item/vnd.googleplus.profile.comm". Yet, it doesn't work as it probably needs additional steps (setting G+ to keep contacts updated and have the contacts in the G+ circles). However, I've somehow succeeded to open the video chat of a person:

        intent =new Intent(Intent.ACTION_VIEW,Uri.parse("content://com.android.contacts/data/"+contactMimeTypeDataId));
        intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT |Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET |Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP);

For Telegram, someone (here) suggested using the next code, but it doesn't work:

        intent = new Intent(android.content.Intent.ACTION_SENDUri.parse("http://telegram.me/"+profile)));
        intent.setPackage("org.telegram.messenger");

It's also possible to just use the phone number, as I wrote here.

For Line, I've found these (based on here and here), but none work:

    Intent intent = new Intent("jp.naver.line.android.intent.action.LINESHORTCUT");
    intent.putExtra("shortcutType", "chatmid");
    intent.putExtra("shortcutTargetId", target);
    intent.putExtra("shortcutTargetName", "");
    intent.putExtra("shortcutFromOS", false);
    startActivity(intent);

Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setData(Uri.parse("line://msg/text/" + getMongon()));

skype: this one works (found from various links, here, for example):

        final String skypeUserName = getSkypeUserName(phone);
        intent = new Intent(Intent.ACTION_VIEW, Uri.parse("skype:" + skypeUserName + "?chat"));

    public String getSkypeUserName(String phoneNumber) {
        if (TextUtils.isEmpty(phoneNumber))
            return null;
        ContentResolver cr = getContentResolver();
        final Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber));
        Cursor cursor = cr.query(uri, new String[]{PhoneLookup.LOOKUP_KEY}, null, null, null);
        if (cursor == null)
            return null;
        final Set<String> contactKeys = new HashSet<>();
        // get contact keys
        {
            final int contactKeyIdx = cursor.getColumnIndex(PhoneLookup.LOOKUP_KEY);
            for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
                String contactKey = cursor.getString(contactKeyIdx);
                contactKeys.add(contactKey);
            }
            cursor.close();
        }
        if (contactKeys.isEmpty())
            return null;
        //get raw ids
        final Set<String> contactRawIdsSet = new HashSet<>();
        {
            final StringBuilder sb = new StringBuilder();
            for (int i = 0; i < contactKeys.size(); ++i)
                sb.append(sb.length() == 0 ? "?" : ",?");
            String inParameters = sb.toString();
            final String[] selectionArgs = contactKeys.toArray(new String[contactKeys.size()]);
            cursor = cr.query(ContactsContract.Data.CONTENT_URI, new String[]{ContactsContract.Data.RAW_CONTACT_ID}, ContactsContract.Data.LOOKUP_KEY + " IN (" + inParameters + ")", selectionArgs, null);
            if (cursor == null)
                return null;
            final int rawContactColIdx = cursor.getColumnIndex(ContactsContract.Data.RAW_CONTACT_ID);
            for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
                String rawContactId = cursor.getString(rawContactColIdx);
                contactRawIdsSet.add(rawContactId);
            }
            cursor.close();
        }
        if (contactRawIdsSet.isEmpty())
            return null;
        //find the skype name
        //TODO think of a better way to query, as it looks weird to search within a set of ids...
        final StringBuilder sb = new StringBuilder();
        for (int i = 0; i < contactRawIdsSet.size(); ++i)
            sb.append(sb.length() == 0 ? "?" : ",?");
        String inParameters = sb.toString();
        final String[] selectionArgs = new String[2 + contactRawIdsSet.size()];
        selectionArgs[0] = "com.skype.contacts.sync";
        selectionArgs[1] = "vnd.android.cursor.item/name";
        int i = 2;
        for (String rawId : contactRawIdsSet)
            selectionArgs[i++] = rawId;
        cursor = cr.query(ContactsContract.Data.CONTENT_URI, new String[]{RawContacts.SOURCE_ID}, ContactsContract.RawContacts.ACCOUNT_TYPE + " = ? AND " + Data.MIMETYPE + " = ? AND " +
                ContactsContract.Data.CONTACT_ID + " IN (" + inParameters + ")", selectionArgs, null);
        if (cursor == null)
            return null;
        if (!cursor.moveToFirst()) {
            cursor.close();
            return null;
        }
        String result = cursor.getString(cursor.getColumnIndex(RawContacts.SOURCE_ID));
        cursor.close();
        return result;
    }
android developer
  • 114,585
  • 152
  • 739
  • 1,270
  • Thanks, but if user never login in FB messenger app, then it navigate to messenger login process but at last it wont open the particular user chat window with whom I have to chat .How to handle such scenario? – Suhas Bachewar Dec 07 '16 at 07:04
  • @SuhasBachewar Well, it makes sense no? In order to chat, you have to login first... Anyway, since this is within FB's chat app, I don't think you can do anything about it. You might be able to know if FB's chat app was opened before, but I don't know if you can check if it's logged in. – android developer Dec 08 '16 at 11:06
  • A bit off topic... Do you how I could initiate a Messenger Audio call programmatically from within my app? – Pascal May 05 '17 at 04:43
  • If facebookId is NOT your user ID, all this will do is launch Messenger as you; it will not enable you to chat with the person you're intending to. You still need to locate that person and therein lies the problem. For example, if you only know the name, you can search for that person by name, but there could be a thousand people having the same name. – FractalBob Jul 03 '17 at 04:01
  • @FractalBob It's not "your user ID". It's of the person you wish to contact with. – android developer Jul 07 '17 at 14:30
  • any idea about Google dou video calling intent the one truecaller is using? – Anwar Kamal Apr 23 '18 at 13:59
  • @AnwarKamal No, but if you do, could be nice if you publish it here ... – android developer Apr 23 '18 at 17:27
  • @Webserveis I already wrote that it didn't work for me. If you have a better one, please write it. – android developer Feb 23 '21 at 08:56
0

it works for me

 try {

            String toNumber = "+91 8*******36"; // contains spaces.
            toNumber = toNumber.replace("+", "").replace(" ", "");

 Intent sendIntent = new Intent(Intent.ACTION_SENDTO,Uri.parse("smsto:" + "" + toNumber + "?body=" + ""));
 sendIntent.putExtra(Intent.EXTRA_TEXT, "hello");
 sendIntent.setPackage("com.whatsapp");
 startActivity(sendIntent);

        }
        catch (Exception e){
            Toast.makeText(getActivity(),"it may be you dont have whats app",Toast.LENGTH_LONG).show();

        }
gaurav gupta
  • 513
  • 1
  • 6
  • 13
  • This is a part of what I wrote. I added protection against the case that the contact doesn't exist there. – android developer Sep 27 '17 at 11:54
  • if "toNumber" is added or not in your contact list yet it will add you automatically – gaurav gupta Sep 27 '17 at 12:03
  • Are you sure? I remember that it doesn't. Instead, I remember it asks you if you wish to add it. – android developer Sep 27 '17 at 12:30
  • i checked then after i have posted – gaurav gupta Sep 27 '17 at 13:12
  • Tried it now. Doesn't automatically add. That's why I added the check, to avoid this dialog. It shows a dialog asking to invite or send SMS. The dialog has a long text : "You seem to be trying to send a WhatsApp message to a phone number that is not registered with WhatsApp. Your contact must have WhatsApp installed in order to chat in WhatsApp. Press 'SMS' to send a normal SMS to this contact, or press 'invite' to send WhatsApp invitation via SMS". – android developer Sep 27 '17 at 14:14
  • without whats app how it will add no. in whats app 's contact – gaurav gupta Sep 28 '17 at 04:14
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/155478/discussion-between-gaurav-gupta-and-android-developer). – gaurav gupta Sep 28 '17 at 06:27
  • That's why the condition is needed. To ensure you can reach this contact, you have to check that it's a WhatsApp-contact. Otherwise you can reach this dialog and can't really chat with this person. – android developer Sep 28 '17 at 07:46
0

Other posts here have good information. I wanted to add for LINE because the information is lacking in many places.

String userId = findUserId();
String sendText = "line://ti/p/~" + userId;
Intent intent = null;
try {
    intent = Intent.parseUri(sendText, Intent.URI_INTENT_SCHEME);
} catch (URISyntaxException e) {
    e.printStackTrace();
}
startActivity(intent);
CMcAllister
  • 176
  • 1
  • 5
  • How do you get `userId` ? What's the code for it? Is it the phone number of the user? – android developer Nov 18 '17 at 07:14
  • The userId is the id that you set in the app personally. It's something that you choose so that you can give to friends. If you search for someone in the app it's by the set userId that you create, or first and last name. The userId in the code is the same as the userId that you set in the app. – CMcAllister Nov 19 '17 at 23:16
  • You mean `userId` is the nickname the person chose for himself? If so, what happens if multiple ones have the same nickname? Can you get the `userId` of all of the people of this app, using some code? What is the code of `findUserId` ? – android developer Nov 20 '17 at 20:31
  • The app makes it so that you have to have a unique id. If someone is already using that id then you can't register it for your account. The original post said that you would like to "open the conversation of a contact". This is how. It will go to a screen with the contact and all you have to do it tap on the contact to open the conversation. As for "findUserId()" if would be what ever you want it to be. It was just an example of what you would need to do to open the app. The only way that I know of to get that userId is to ask a friend, and they will tell you. – CMcAllister Nov 22 '17 at 02:30
  • So you say it's impossible to know the id of the user, using code? Only by manually checking, as a user, what's the id? Where is it found? In the app? – android developer Nov 22 '17 at 17:24
  • Not that it's impossible, just that this is not what the code does. I personally don't know how if there is in fact a way. Yes the ID is found in the app. If your friend wants you to find you, he gives it to you and then you are friends. – CMcAllister Nov 23 '17 at 20:39