【问题标题】:How to open specific contact chat screen in various popular chat/social-networks apps?如何在各种流行的聊天/社交网络应用程序中打开特定的联系人聊天屏幕?
【发布时间】:2016-06-28 14:14:46
【问题描述】:

背景

我发现有一种方法可以在 WhatsApp 上打开特定的联系人对话屏幕,here

不仅如此,我还发现一个名为“Drupe”的应用也能做到这一点,甚至更多:

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

问题

我找不到任何官方API可以这样打开它,所以我不确定它有多安全。

我找到了 SDK,但没有找到意图说明。

问题

我想了解更多关于各种社交网络和聊天应用程序可用的信息:

  • WhatsApp
  • Facebook 信使
  • Viber
  • 电报
  • 环聊

可能的特征可能是:

  • 打开联系人的对话,当输入的是他的电话号码时
  • 有一个可以在新屏幕中发送的新文本
  • 对于 Facebook,也许还可以使用该人的 Facebook-ID(这意味着这是输入)而不是电话号码来打开。

这些功能是否适用于这些社交网络和聊天应用程序?

【问题讨论】:

  • 为什么要投票结束这个?对于whatsapp 可以,但对于其他人就不行?
  • 对于 Facebook 没有官方的方式。 Facebook 平台政策也不允许预填充文本

标签: android facebook whatsapp telegram viber


【解决方案1】:

对于 Facebook 信使,我找到了这个(来自 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));

它有效,但我想知道是否有其他方法可以访问它(例如使用电话号码)。


对于 WhatsApp,我发现了这个(来自 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;
}

它可以工作,但它不会添加消息。它也可能会说联系人没有 WhatsApp。


对于 Viber,我找到了这个(来自 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;
}

对于环聊,它似乎与 Viber 类似,但具有以下 mimetype:“vnd.android.cursor.item/vnd.googleplus.profile.comm”。然而,它不起作用,因为它可能需要额外的步骤(设置 G+ 以保持联系人更新并让联系人进入 G+ 圈子)。但是,我以某种方式成功打开了一个人的视频聊天:

        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);

对于 Telegram,有人 (here) 建议使用下一个代码,但它不起作用:

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

对于 Line,我找到了这些(基于 herehere),但没有一个工作:

    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:这个有效(从各种链接中找到,例如here):

        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;
    }

【讨论】:

  • 谢谢,但是如果用户从未登录 FB messenger 应用程序,那么它会导航到 messenger 登录过程,但最后它不会打开我必须与之聊天的特定用户聊天窗口。如何处理这种情况?
  • @SuhasBachewar 嗯,有道理,不是吗?为了聊天,你必须先登录......无论如何,因为这是在FB的聊天应用程序中,我认为你无能为力。你或许能知道FB的聊天应用之前有没有被打开过,但不知道你能不能检查它是否已经登录。
  • 有点跑题了......你知道如何在我的应用程序中以编程方式发起 Messenger Audio 通话吗?
  • 如果 facebookId 不是您的用户 ID,那么这一切都会像您一样启动 Messenger;它不会让您与您打算聊天的人聊天。你仍然需要找到那个人,这就是问题所在。例如,如果您只知道姓名,则可以按姓名搜索该人,但可能有一千个人同名。
  • @FractalBob 这不是“你的用户 ID”。这是您希望联系的人。
【解决方案2】:

对我有用

 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();

        }

【讨论】:

  • 这是我写的一部分。我添加了对联系人不存在的情况的保护。
  • 如果您的联系人列表中添加了“toNumber”,但它会自动添加您
  • 你确定吗?我记得它没有。相反,我记得它会询问您是否要添加它。
  • 我发帖后检查了
  • 现在试过了。不会自动添加。这就是我添加检查的原因,以避免出现此对话框。它显示一个对话框,要求邀请或发送短信。该对话框有很长的文字:“您似乎正试图向未在 WhatsApp 注册的电话号码发送 WhatsApp 消息。您的联系人必须安装 WhatsApp 才能在 WhatsApp 中聊天。按“短信”发送正常向此联系人发送短信,或按“邀请”以通过短信发送 WhatsApp 邀请”。
【解决方案3】:

这里的其他帖子有很好的信息。我想为LINE添加,因为很多地方缺少信息。

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);

【讨论】:

  • 你如何得到userId ?它的代码是什么?是用户的电话号码吗?
  • userId是你个人在app中设置的id。这是您选择的东西,以便您可以送给朋友。如果您在应用程序中搜索某人,则使用您创建的 set userId 或名字和姓氏。代码中的userId与您在应用中设置的userId一致。
  • 你的意思是userId是那个人给自己取的昵称?如果是这样,如果多个昵称具有相同的昵称怎么办?你能用一些代码得到这个应用程序所有人的userId吗? findUserId的代码是什么?
  • 该应用程序使您必须拥有唯一的ID。如果有人已经在使用该 ID,则您无法将其注册到您的帐户中。原帖说你想“打开一个联系人的对话”。就是这样。它将与联系人一起进入屏幕,您只需点击联系人即可打开对话。至于“findUserId()”如果是你想要的。这只是打开应用程序所需要做的一个示例。据我所知,获取该 userId 的唯一方法是询问朋友,他们会告诉你。
  • 所以你说不可能知道用户的id,用code?仅通过手动检查,作为用户,id 是什么?它在哪里找到?在应用中?
猜你喜欢
  • 2018-12-08
  • 2016-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-05
相关资源
最近更新 更多