如何在各种流行的聊天/社交网络应用程序中打开特定的联系人聊天屏幕?

2024-01-14

背景

我发现有一种方法可以在 WhatsApp 上打开特定的联系人对话屏幕,here https://stackoverflow.com/q/16121163/878126 .

不仅如此,我还发现了一个名为“" 做同样的事情,甚至可能更多:

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

问题

我找不到任何官方API可以通过这种方式打开它,所以我不确定它的安全性。

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

问题

我想详细了解各种社交网络和聊天应用程序的可用功能:

  • WhatsApp
  • 脸书信使
  • Viber
  • Line
  • Telegram
  • Hangouts

可能的特征可能是:

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

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


对于 Facebook-messenger,我发现了这个(来自https://developers.facebook.com/docs/messenger-platform/discovery/m-me-links#format 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 https://stackoverflow.com/q/15462874/878126) :

    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。

正如我所写,也可以只使用电话号码here https://stackoverflow.com/a/73317181/878126.


对于 Viber,我找到了这个(来自here http://infostart.ru/public/301851/) :

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

对于 Hangouts,它似乎与 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 https://stackoverflow.com/a/34845285/878126)建议使用下一个代码,但它不起作用:

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

正如我所写,也可以只使用电话号码here https://stackoverflow.com/a/73317181/878126.

对于 Line,我找到了这些(基于here http://www.binzume.net/diary/2012-11-09:A1 and here http://ichrevo-se.jugem.jp/?eid=22),但没有一个工作:

    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 https://stackoverflow.com/q/10132556/878126, 例如):

        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;
    }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在各种流行的聊天/社交网络应用程序中打开特定的联系人聊天屏幕? 的相关文章

  • JKS、BKS 和 PKCS12 文件格式

    我正在设置一个无头服务器 该服务器使用用户提供的数据 JS CSS HTML 密钥库 为 Android 构建 Phonegap 混合应用程序 我想进行一些基本的客户端检查 以确保上传的密钥库有效 对于 JKS 文件 我发现可以通过确保提供
  • 应用程序启动时立即隐藏导航栏

    基于以下代码片段 我能够隐藏状态栏当应用程序启动时 但不是导航栏 由后退 主页和任务管理器按钮组成的栏 因为它隐藏了稍后在 MainActivity 的线程完成加载后 这是清单
  • iOS 中的 FacebookSDK 不显示关闭按钮且无法关闭

    您好 我已经为 iOS 6 应用程序集成了 Facebook SDK Facebook 身份验证和共享工作完美 但没有提供关闭 FB 对话框的规定 当FB对话框打开时 只有在身份验证成功后才会关闭 没有关闭或导航回来的规定 我如何制作关闭按
  • Android,无法从谷歌API获取天气

    以下代码之前运行良好 class RetreiveWeatherTask extends AsyncTask
  • API 31 上是否有官方方法来提供文件关联,可能使用 pathSuffix/pathAdvancedPattern?

    背景 现代桌面操作系统上的一个众所周知的功能是能够处理文件 允许用户从文件管理器和其他应用程序中打开它们 作为 文件关联 配置 问题 到目前为止 对于用户和开发人员来说 在 Android 上设置文件类型关联并不是一件很方便的事情 在 An
  • 检查 Firebase 邀请是否引导至 Play 商店

    当在 Android 上使用 Firebase 邀请并在应用程序启动时访问动态链接时 有没有办法知道用户是通过邀请刚刚安装了该应用程序还是已经安装了该应用程序 非常感谢 Borja 编辑 感谢 Catalin Morosan 的回答 事实证
  • Android Activity 和 Service 关系 - 暂停后、停止后

    假设创建了 Activity A 然后 A 启动了一个 Service S 并将其自身绑定到 S S 通知 A 更新 这将导致 A 的状态发生变化 Android 暂停或停止 A 后 A 和 S 会发生什么 例如 暂停 A 是否会自动解除它
  • Droid 3 上的列表视图背景为灰色

    我有一个带有自定义背景的列表框 它在黑色背景的两侧显示一条细白线 在我所有的测试手机 Galaxy Captivate Vibrant Nexus 1 G Tablet Archos 32 Droid 上运行良好 我刚买了一台 Droid
  • 适用于 Droid 手机的数学或 LaTeX 引擎 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 Android 手机有可用的数学或 LaTeX 引擎吗 我最喜欢的抽认卡应用程序 AnyMemo 似乎
  • Android 视图上的动态气泡

    任何人都可以如何在Android布局上制作可点击的动态气泡 我的设计师对屏幕的想法如下 我的图像中所有气泡都是分配给用户的一组任务 气泡的标签根据任务而变化 1 1 根据我的项目要求 颜色和半径将根据 api 响应而变化 您能建议任何演示或
  • 在 Android 5 上支持 BLE 外设角色的芯片组 [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 Android 5 0 Lollipop 引入的新 BLE 外设模式将不会在 Nexus 4 5 或 7 上启用 https code
  • Android - 具有可序列化对象的 SharedPreferences

    我知道 SharedPreferences 有putString putFloat putLong putInt and putBoolean 但我需要存储一个类型的对象Serializable in SharedPreferences 我
  • android sqlite 如果不存在则创建表

    创建新表时遇到一点问题 当我使用 CREATE TABLE 命令时 我的新表按应有的方式形成 但是当我退出活动时 应用程序崩溃 并且我在 logcat 中得到一个表已存在 如果我使用 CREATE TABLE IF NOT EXISTS 则
  • 如何将 currentTimeMillis 转换为可读的日期格式? [复制]

    这个问题在这里已经有答案了 我想用currentTimeMillis两次 这样我就可以计算持续时间 但我也想以用户可读的格式显示时间和日期 我遇到了麻烦currentTimeMillis有利于计算 但我看不到内置函数可以转换为合适的时间或时
  • 当创建 Android Jetpack Compose AndroidView 的参数发生变化时,如何替换它?

    我有一个应用程序 显示封装在其中的几个不同视图AndroidView 在下面重现的简单示例中 这些只是TextView实例 问题是更改文本 在本例中循环显示三个不同的值 似乎不会更新应用程序显示的内容 sealed class AppVie
  • 日志记录在 Android 设备上实际上有什么作用?

    我一直在 Android 示例中看到这样的代码 try catch Exception e Log e Error e getMessage 什么是Log e实际上在物理设备上做什么 它进入系统日志 开发人员可以通过 SDK 工具访问该日志
  • 如何在Webview中保存用户名和密码

    目前 我还在学习Android开发的过程中 所以如果我的这个问题对你来说不太容易理解 请原谅 我创建了一个 Android 应用程序 它使用 RecyclerView 显示一组列表 当用户单击列表中的每个名称时 它会将它们重定向到一组不同的
  • Activity 上的 OnTouchListener 从不调用

    我使用了这段代码 但是当我在运行时单击活动时 它永远不会在 OnTouch 方法中命中 有人可以指导我我做错了什么吗 我需要设置此活动的内容视图吗 实际上我想要用户在执行过程中触摸的活动的坐标 public class TouchTestA
  • Android应用程序中的模式输入

    我想知道是否有其他替代方案可以替代 Android 上平庸的 EditText 密码输入 是否有 API 或开源代码可以集成到我的应用程序中 类似于锁屏图案解锁 Intent 可能会返回哈希值 数字 字符串或代表用户输入的模式的任何内容 我
  • RecyclerView 适配器的 Kotlin 泛型

    我正在尝试编写一个通用的 recyclerview 适配器 我找到了几个例子 然而 仍然无法弄清楚如何实现通用适配器 我写的代码是 open abstract class BaseAdapter

随机推荐