如何在各种流行的聊天/社交网络应用程序中打开特定的联系人聊天屏幕?
Posted
技术标签:
【中文标题】如何在各种流行的聊天/社交网络应用程序中打开特定的联系人聊天屏幕?【英文标题】: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 平台政策也不允许预填充文本 【参考方案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,我找到了这些(基于 here 和 here),但没有一个工作:
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 是什么?它在哪里找到?在应用中?以上是关于如何在各种流行的聊天/社交网络应用程序中打开特定的联系人聊天屏幕?的主要内容,如果未能解决你的问题,请参考以下文章