I want to make start a telegram video call from inside my android app, so I have decompiled the new telegram apk to find the following:
<intent-filter>
<action
android:name="android.intent.action.VIEW" />
<category
android:name="android.intent.category.DEFAULT" />
<data
android:mimeType="vnd.android.cursor.item/vnd.org.telegram.messenger.android.profile" />
<data
android:mimeType="vnd.android.cursor.item/vnd.org.telegram.messenger.android.call" />
<data
android:mimeType="vnd.android.cursor.item/vnd.org.telegram.messenger.android.call.video" />
</intent-filter>
There is something related to call.video, but I don't know how to use this data element in the code, my only try was to do the following:
Intent telegram = new Intent(Intent.ACTION_VIEW ,
Uri.parse("https://telegram.me/"+contact));
startActivity(telegram);
I expect something like telegram.setType("video"); or telegram.setType("vnd.android.cursor.item/vnd.org.telegram.messenger.android.call.video").
Is it possible at the end ?
Thanks in advance
You need to use URI contactID with mimeType which is "vnd.android.cursor.item/vnd.org.telegram.messenger.android.call.video". Looking first contactID by number phone:
private String getContactIdByPhoneNumber(String phoneNumber) {
ContentResolver contentResolver = getContentResolver();
String contactId = null;
Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber));
String[] projection = new String[]{ContactsContract.PhoneLookup._ID};
Cursor cursor = contentResolver.query(uri, projection, null, null, null);
if (cursor != null) {
while (cursor.moveToNext()) {
contactId = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.PhoneLookup._ID));
}
cursor.close();
}
return contactId;
}
then use this contactID and mimeType to find URI:
private Uri getUriFromPhoneNumber(String phoneNumber) {
Uri uri = null;
String contactId = getContactIdByPhoneNumber(phoneNumber);
String mimeTypeTelegram = "vnd.android.cursor.item/vnd.org.telegram.messenger.android.call.video";
Cursor cursorTelegram = getContentResolver().query(
ContactsContract.Data.CONTENT_URI,
new String[]{ContactsContract.Data._ID},
ContactsContract.Data.CONTACT_ID + "=? AND " + ContactsContract.Data.MIMETYPE + "=?",
new String[]{contactId, mimeTypeTelegram}, null);
if (cursorTelegram != null) {
while (cursorTelegram.moveToNext()) {
String id = cursorTelegram.getString(cursorTelegram.getColumnIndexOrThrow(ContactsContract.Data._ID));
if (!TextUtils.isEmpty(id)) {
uri = Uri.parse(ContactsContract.Data.CONTENT_URI + "/" + id);
break;
}
}
cursorTelegram.close();
}
return uri;
}
after which use Intent.ACTION_VIEW:
public void videoCallToTelegramContact(String phoneNumber) {
Uri uri = getUriFromPhoneNumber(phoneNumber);
Log.d(TAG, uri + "");
if (uri != null) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(uri);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
}
It would be nice to add a check for the installed 'Telegram', as well as whether the user has allowed the video call.
Related
I am creating an audio player and i am using this code to get all the songs
String[] STAR = {"*"};
Cursor cursor;
Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
String selection = MediaStore.Audio.Media.IS_MUSIC + " != 0";
File file;
cursor =context.getContentResolver().query(uri, STAR, selection, null, null);
if (cursor != null) {
if (cursor.moveToFirst()) {
int i = 0;
do {
String songName = cursor
.getString(cursor
.getColumnIndex(MediaStore.Audio.Media.DISPLAY_NAME));
path[i] = cursor.getString(cursor
.getColumnIndex(MediaStore.Audio.Media.DATA));
String albumName = cursor.getString(cursor
.getColumnIndex(MediaStore.Audio.Media.ALBUM));
albumId[i] = cursor
.getInt(cursor
.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));
String artist= cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST));
String albumname= cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM));
artistId[i]=cursor.getInt(cursor
.getColumnIndex(MediaStore.Audio.Media.ARTIST_ID));
}cursor.close();
This gets me the songs but i get audio of unsupported formats too. such as .wav any idea how to avoid unsupported formats
You can use MimeType to do this. See below example code how it is done for mp3.
ContentResolver contentResolver = context.getContentResolver();
Uri uri = MediaStore.Files.getContentUri("external");
String[] projection = null;
String sortOrder = null;
String selectionMimeType = MediaStore.Files.FileColumns.MIME_TYPE + "=?";
String mimeType = imeTypeMap.getSingleton().getMimeTypeFromExtension("mp3");
String[] selectionArgsMp3 = new String[]{ mimeType };
Cursor mp3Songs = contentResolver.query(uri, projection,selectionMimeType,selectionArgsmp3, sortOrder);
Another approach it that you can check is there any compatible application installed on device using below code while opening/playing application.
private void openRelevantFileHandler(String pathToMusicFile)
{
String extension = MimeTypeMap.getFileExtensionFromUrl(pathToMusicFile);
String type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse("file://" + pathToMusicFile), type);
PackageManager packageManager = context.getPackageManager();
List activities = packageManager.queryIntentActivities(intent, PackageManager.MATCH_ALL);
boolean isIntentSafe = activities.size() > 0;
if (!isIntentSafe) {
Utility.showToast(context, "No application available on your device to open this type of file.");
}
else
{
context.startActivity(intent);//Start related application
}
}
Hope this will help you in some way :)
My Manifest activity code
<activity android:name="FileReceiver" >
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="image/*" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND_MULTIPLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="image/*" />
</intent-filter>
</activity>
My Activity code :
Intent i = getIntent();
String action = i.getAction();
if (action.equals(Intent.ACTION_SEND)) {
Uri imageUri = (Uri) i.getParcelableExtra(Intent.EXTRA_STREAM);
if (imageUri != null) {
Log.i("1234567", "URI : " + imageUri);
Log.i("123456", "path :" + imageUri.getPath());
File source = null;
source = new File(imageUri.getPath());
String fileNme = "/" + source.getName();
File destination = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + path);
Log.i("123456", "destination path :" + destination);
try {
FileUtils.copyFile(source, destination);
} catch (IOException e) {
Log.i("123456", "IO Exception");
e.printStackTrace();
}
}
im getting exception
01-09 16:10:09.756: W/System.err(30225): java.io.FileNotFoundException: Source 'content:/media/external/images/media/127' does not exist
how do i get the path of the image when i receive an image from DCIM folder ?
/**
* helper to retrieve the path of an image URI
*/
public String getPath(Uri uri) {
// just some safety built in
if( uri == null ) {
// TODO perform some logging or show user feedback
return null;
}
// try to retrieve the image from the media store first
// this will only work for images selected from gallery
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(uri, projection, null, null, null);
if( cursor != null ){
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
// this is our fallback here
return uri.getPath();
}
source:
Get/pick an image from Android's built-in Gallery app programmatically
I've got the same problem. Solved it using the following code:
public static String getPathFromURI(Context context, Uri contentUri) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT &&
DocumentsContract.isDocumentUri(context, contentUri)) {
return getPathForV19AndUp(context, contentUri);
} else {
return getPathForPreV19(context, contentUri);
}
}
private static String getPathForPreV19(Context context, Uri contentUri) {
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = context.getContentResolver().query(contentUri, projection, null, null, null);
if (cursor != null && cursor.moveToFirst()) {
try {
int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
return cursor.getString(columnIndex);
} finally {
cursor.close();
}
}
return null;
}
#TargetApi(Build.VERSION_CODES.KITKAT)
private static String getPathForV19AndUp(Context context, Uri contentUri) {
String documentId = DocumentsContract.getDocumentId(contentUri);
String id = documentId.split(":")[1];
String[] column = { MediaStore.Images.Media.DATA };
String sel = MediaStore.Images.Media._ID + "=?";
Cursor cursor = context.getContentResolver().
query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
column, sel, new String[]{ id }, null);
if (cursor != null) {
try {
int columnIndex = cursor.getColumnIndex(column[0]);
if (cursor.moveToFirst()) {
return cursor.getString(columnIndex);
}
} finally {
cursor.close();
}
}
return null;
}
I'm displaying a list of Contacts, and have a context menu to Edit Contact by calling an intent. On some contacts it works fine, but on others the Edit Contact activity is blank. Any ideas?
Here is the cursor...
projection = new String[]{ContactsContract.CommonDataKinds.Phone.NUMBER,ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,ContactsContract.CommonDataKinds.Phone._ID};
uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
cursor = getActivity().getContentResolver().query(uri, projection, null, null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC");
Here is the code from my CursorAdapter.getView() ...
textView.setText(cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)) ;
And here is the code from my onContextItemSelected...
cursor.moveToPosition(position);
String idContact = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
Intent i = new Intent(Intent.ACTION_EDIT);
i.setData(Uri.parse(ContactsContract.Contacts.CONTENT_LOOKUP_URI + "/" + idContact));
parent.startActivity(i);
I've checked logcat and can see
I/ActivityManager( 102): Starting activity: Intent { act=android.intent.action.EDIT dat=content://com.android.contacts/contacts/lookup/23356 cmp=com.android.htccontacts/.ui.EditContactActivity }
but no error messges
Try this:
Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
Cursor cursor = this.getContentResolver().query(uri, null, null, null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC");
long idContact = cursor.getLong(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID));
then
Intent i = new Intent(Intent.ACTION_EDIT);
Uri contactUri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, idContact);
i.setData(contactUri);
I am working with Android Contact ContentProvider. I have a Phone Number and I need to get the URI of the Photo of the contact associated with this phone number. How can I do it???
I know I can get the raw data of the photo and build an InputStream, but I dont want the input stream, I need the URI.
EDIT: Originally I'm using following code to fetch contact info
Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNo));
Cursor cursor = context.getContentResolver().query(uri, details, null, null, null);
To get the conatct id using the phone number use the following code:
import android.provider.ContactsContract.PhoneLookup;
public String fetchContactIdFromPhoneNumber(String phoneNumber) {
Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI,
Uri.encode(phoneNumber));
Cursor cursor = this.getContentResolver().query(uri,
new String[] { PhoneLookup.DISPLAY_NAME, PhoneLookup._ID },
null, null, null);
String contactId = "";
if (cursor.moveToFirst()) {
do {
contactId = cursor.getString(cursor
.getColumnIndex(PhoneLookup._ID));
} while (cursor.moveToNext());
}
return contactId;
}
and use the contact id obtained to get the contatc photo URI. Use the following code for getting photo URI:
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.Phone;
public Uri getPhotoUri(long contactId) {
ContentResolver contentResolver = getContentResolver();
try {
Cursor cursor = contentResolver
.query(ContactsContract.Data.CONTENT_URI,
null,
ContactsContract.Data.CONTACT_ID
+ "="
+ contactId
+ " AND "
+ ContactsContract.Data.MIMETYPE
+ "='"
+ ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE
+ "'", null, null);
if (cursor != null) {
if (!cursor.moveToFirst()) {
return null; // no photo
}
} else {
return null; // error in cursor process
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
Uri person = ContentUris.withAppendedId(
ContactsContract.Contacts.CONTENT_URI, contactId);
return Uri.withAppendedPath(person,
ContactsContract.Contacts.Photo.CONTENT_DIRECTORY);
}
Hope this would help.
This solution demonstrates how to get an image from a user contact and then display it in an ImageView.
ImageView profile = (ImageView)findViewById(R.id.imageView1);
Uri my_contact_Uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_URI, String.valueOf(Contact_Id));
InputStream photo_stream = ContactsContract.Contacts.openContactPhotoInputStream(getContentResolver(),my_contact_Uri);
BufferedInputStream buf =new BufferedInputStream(photo_stream);
Bitmap my_btmp = BitmapFactory.decodeStream(buf);
profile.setImageBitmap(my_btmp);
Here's the code from Android Documentation.
Uri contactUri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, contactId);
return Uri.withAppendedPath(contactUri, ContactsContract.Contacts.Photo.CONTENT_DIRECTORY);
You can get PHOTO_URI by NUMBER just use following code also you can use _ID.
public static String getContactPhoto(Context context, String phoneNumber) {
ContentResolver cr = context.getContentResolver();
Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber));
Cursor cursor = cr.query(uri, new String[]{ContactsContract.PhoneLookup.PHOTO_URI}, null, null, null);
if (cursor == null) {
return null;
}
String contactImage= null;
if (cursor.moveToFirst()) {
contactImage= cursor.getString(cursor.getColumnIndex(ContactsContract.PhoneLookup.PHOTO_URI));
}
if (!cursor.isClosed()) {
cursor.close();
}
return contactImage;
}
final boolean IS_HONEYCOMB = Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB;
String phoneNumber = "+1 416 385 7805";
ContentResolver contentResolver = context.getContentResolver();
Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber));
String[] projection = new String[] {
ContactsContract.Contacts._ID,
ContactsContract.Contacts.LOOKUP_KEY,
IS_HONEYCOMB ? ContactsContract.Contacts.PHOTO_THUMBNAIL_URI : ContactsContract.Contacts._ID,
};
Cursor cursor =
contentResolver.query(
uri,
projection,
null,
null,
null);
if (cursor != null && cursor.moveToNext()) {
long contactId = cursor.getLong(0);
String lookupKey = cursor.getString(1);
String thumbnailUri = cursor.getString(2);
cursor.close();
}
So now if sdk is honeycomb or higher u have thumbnail uri of the contact.
Or you can construct a lookup uri like this:
Uri uri = ContactsContract.Contacts.getLookupUri(contactId, lookupKey);
P.S. If you already know contact id and/or lookup key you can construct a Uri from string:
lookup: content://com.android.contacts/contacts/lookup/{lookup key}/{contact id}
thumbnail: content://com.android.contacts/contacts/{contact id}/photo
So it's better to cache these values.
I would like to retrieve the name of a contact associated with an incoming telephone number. As I process the incoming number in the broascastreceiver having a String with the name of the incoming caller would help my project greatly.
I would think this involves a query using the sql WHERE clause as a filter, but do I need to sort the contacts? An example or hint would be of great assistance.
Although this has already been answered, but here is the complete function to get the contact name from number. Hope it will help others:
public static String getContactName(Context context, String phoneNumber) {
ContentResolver cr = context.getContentResolver();
Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber));
Cursor cursor = cr.query(uri, new String[]{PhoneLookup.DISPLAY_NAME}, null, null, null);
if (cursor == null) {
return null;
}
String contactName = null;
if(cursor.moveToFirst()) {
contactName = cursor.getString(cursor.getColumnIndex(PhoneLookup.DISPLAY_NAME));
}
if(cursor != null && !cursor.isClosed()) {
cursor.close();
}
return contactName;
}
[Updating based on Marcus's comment]
You will have to ask for this permission:
<uses-permission android:name="android.permission.READ_CONTACTS"/>
For that you need to use the optimized PhoneLookup provider as described.
Add the permission to AndroidManifest.xml:
<uses-permission android:name="android.permission.READ_CONTACTS"/>
Then:
public String getContactName(final String phoneNumber, Context context)
{
Uri uri=Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI,Uri.encode(phoneNumber));
String[] projection = new String[]{ContactsContract.PhoneLookup.DISPLAY_NAME};
String contactName="";
Cursor cursor=context.getContentResolver().query(uri,projection,null,null,null);
if (cursor != null) {
if(cursor.moveToFirst()) {
contactName=cursor.getString(0);
}
cursor.close();
}
return contactName;
}
This was very helpful, here's my final code for retrieving the caller's Name, id, and Photo:
private void uploadContactPhoto(Context context, String number) {
Log.v("ffnet", "Started uploadcontactphoto...");
String name = null;
String contactId = null;
InputStream input = null;
// define the columns I want the query to return
String[] projection = new String[] {
ContactsContract.PhoneLookup.DISPLAY_NAME,
ContactsContract.PhoneLookup._ID};
// encode the phone number and build the filter URI
Uri contactUri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number));
// query time
Cursor cursor = context.getContentResolver().query(contactUri, projection, null, null, null);
if (cursor.moveToFirst()) {
// Get values from contacts database:
contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.PhoneLookup._ID));
name = cursor.getString(cursor.getColumnIndex(ContactsContract.PhoneLookup.DISPLAY_NAME));
// Get photo of contactId as input stream:
Uri uri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, Long.parseLong(contactId));
input = ContactsContract.Contacts.openContactPhotoInputStream(context.getContentResolver(), uri);
Log.v("ffnet", "Started uploadcontactphoto: Contact Found # " + number);
Log.v("ffnet", "Started uploadcontactphoto: Contact name = " + name);
Log.v("ffnet", "Started uploadcontactphoto: Contact id = " + contactId);
} else {
Log.v("ffnet", "Started uploadcontactphoto: Contact Not Found # " + number);
return; // contact not found
}
// Only continue if we found a valid contact photo:
if (input == null) {
Log.v("ffnet", "Started uploadcontactphoto: No photo found, id = " + contactId + " name = " + name);
return; // no photo
} else {
this.type = contactId;
Log.v("ffnet", "Started uploadcontactphoto: Photo found, id = " + contactId + " name = " + name);
}
... then just do whatever you want with "input" (their photo as an InputStream), "name", and "contactId".
And here are the docs listing the ~15 or so columns you have access to, just add them to the projection near the start of the code up above:
http://developer.android.com/reference/android/provider/ContactsContract.PhoneLookup.html
This version is the same as Vikram.exe's answer with code to avoid the ANR
interface GetContactNameListener {
void contactName(String name);
}
public void getContactName(final String phoneNumber,final GetContactNameListener listener) {
new Thread(new Runnable() {
#Override
public void run() {
ContentResolver cr = getContentResolver();
Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber));
Cursor cursor = cr.query(uri, new String[]{ContactsContract.PhoneLookup.DISPLAY_NAME}, null, null, null);
if (cursor == null) {
return;
}
String contactName = null;
if(cursor.moveToFirst()) {
contactName = cursor.getString(cursor.getColumnIndex(ContactsContract.PhoneLookup.DISPLAY_NAME));
}
if(cursor != null && !cursor.isClosed()) {
cursor.close();
}
listener.contactName(contactName);
}
}).start();
}
Pass the contact number from which you are getting the call in the following method. This Method will check whether the contact is saved in your mobile or not. If the contact is saved then it will return the contact name otherwise it return a string unknown number
Add this code in your Broadcast receiver class
public String getContactDisplayNameByNumber(String number,Context context) {
Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number));
name = "Incoming call from";
ContentResolver contentResolver = context.getContentResolver();
Cursor contactLookup = contentResolver.query(uri, null, null, null, null);
try {
if (contactLookup != null && contactLookup.getCount() > 0) {
contactLookup.moveToNext();
name = contactLookup.getString(contactLookup.getColumnIndex(ContactsContract.Data.DISPLAY_NAME));
// this.id =
// contactLookup.getString(contactLookup.getColumnIndex(ContactsContract.Data.CONTACT_ID));
// String contactId =
// contactLookup.getString(contactLookup.getColumnIndex(BaseColumns._ID));
}else{
name = "Unknown number";
}
} finally {
if (contactLookup != null) {
contactLookup.close();
}
}
return name;
}
to get Source code visit this link
For that, we can use the PhoneLookup provider to get the names or contact details using the mobile number.
Add the permission to AndroidManifest.xml:
<uses-permission android:name="android.permission.READ_CONTACTS"/>
Add the following custom kotlin method in your activity and call the same with the required mobile number.
fun getContactNameByPhoneNumber(context: Context, phoneNumber: String): String? {
var phone = phoneNumber
if(phoneNumber != null && phoneNumber.length > 0 && phoneNumber[0].equals('+'))
phone = phoneNumber.substring(3)
val projection = arrayOf(
ContactsContract.PhoneLookup.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.NUMBER
)
val cursor = context.contentResolver.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
projection,
ContactsContract.CommonDataKinds.Phone.NUMBER, null, null
) ?: return ""
for (i in 0 until cursor.count) {
cursor.moveToPosition(i)
val nameFieldColumnIndex = cursor
.getColumnIndex(ContactsContract.PhoneLookup.DISPLAY_NAME)
val phoneFieldColumnIndex = cursor
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)
if(phone.equals(cursor.getString(phoneFieldColumnIndex)))
return cursor.getString(nameFieldColumnIndex)
}
return "Unknown"
}
For more: https://developer.android.com/training/contacts-provider/retrieve-names