Ausgabe
Hintergrund
Ich habe herausgefunden, dass es hier eine Möglichkeit gibt, einen bestimmten Konversationsbildschirm für Kontakte auf WhatsApp zu öffnen .
Nicht nur das, sondern ich habe herausgefunden, dass eine App namens „ Drupe “ dasselbe tut, und vielleicht sogar noch mehr:
Das Problem
Ich kann keine offizielle API finden, um es auf diese Weise zu öffnen, daher bin ich mir nicht sicher, wie sicher es ist.
Ich habe SDKs gefunden, aber keine Absichtsanweisungen.
Die Fragen
Ich möchte mehr darüber erfahren, was für verschiedene soziale Netzwerke und Chat-Apps verfügbar ist:
- Facebook Messenger
- Viber
- Linie
- Telegramm
- Treffpunkte
Mögliche Merkmale können sein:
- Öffnen Sie die Konversation eines Kontakts, wenn seine Telefonnummer eingegeben wird
- haben einen neuen Text, der bereit ist, auf dem neuen Bildschirm gesendet zu werden
- für Facebook möglicherweise auch mit der Facebook-ID der Person (d. h. dies ist die Eingabe) anstelle einer Telefonnummer öffnen können.
Sind solche Funktionen für jedes dieser sozialen Netzwerke und Chat-Apps verfügbar?
Lösung
Für Facebook-Messenger habe ich Folgendes gefunden (von 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));
Es funktioniert, aber ich frage mich, ob es eine andere Möglichkeit gibt, darauf zuzugreifen (z. B. über die Telefonnummer).
Für WhatsApp habe ich das gefunden (von hier ):
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;
}
Es funktioniert, aber es fügt die Nachricht nicht hinzu. Es könnte auch sagen, dass der Kontakt kein WhatsApp hat.
Es ist auch möglich, nur die Telefonnummer zu verwenden, wie ich hier geschrieben habe .
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: dieser funktioniert (gefunden von verschiedenen links, hier , zum beispiel):
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;
}
Beantwortet von – Android-Entwickler
Antwort geprüft von – Jay B. (FixError Admin)