I want to load cover audio art in android for show list of audio from device. For this purpose i used this following Link:
way1
way2
way3
Like following picture:
And my code for Load audio files:
private void loadAudio() {
ContentResolver contentResolver = getContentResolver();
Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
String selection = MediaStore.Audio.Media.IS_MUSIC + "!= 0";
String sortOrder = MediaStore.Audio.Media.TITLE + " ASC";
Cursor cursor = contentResolver.query(uri, null, selection, null, sortOrder);
if (cursor != null && cursor.getCount() > 0) {
audioList.clear();
while (cursor.moveToNext()) {
String data = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA));
String title = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.TITLE));
String album = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM));
String artist = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST));
int albumId = cursor.getInt(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));
Cursor cursor1 = contentResolver.query(MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI,
new String[]{MediaStore.Audio.Albums._ID, MediaStore.Audio.Albums.ALBUM_ART},
MediaStore.Audio.Albums._ID + "=" + albumId, null, null);
Bitmap bitmap = null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) {
try {
bitmap = contentResolver.loadThumbnail(MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, new Size(30, 30), null);
} catch (IOException e) {
e.printStackTrace();
}
}
String albumArt = "";
if (cursor1 != null && cursor1.getCount() > 0)
while (cursor1.moveToNext()) {
albumArt = cursor.getString(cursor1.getColumnIndex(MediaStore.Audio.Albums.ALBUM_ART));
}
// Save to audioList
audioList.add(new Audio(data, title, album, artist, albumArt, bitmap));
}
}
cursor.close();
setAdapter();
}
And in MyAdapter about recyclerview:
#Override
public void onBindViewHolder(#NonNull MainHolder holder, int position) {
Audio audio = arrayList.get(position);
holder.txtTitle.setText("Title: " + audio.getTitle());
holder.txtAlbum.setText("Album: " + audio.getAlbum());
holder.txtArtist.setText("Artist: " + audio.getArtist());
File imgFile = new File(audio.getAlbumArt());
Picasso.get().load(imgFile.getAbsolutePath()).into(holder.img);
if (imgFile.exists()) {
Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
holder.img.setImageBitmap(myBitmap);
}
}
Help me please.
Solved:
Load audio file:
private void loadAudio() {
ContentResolver contentResolver = getContentResolver();
Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
String selection = MediaStore.Audio.Media.IS_MUSIC + "!= 0";
String sortOrder = MediaStore.Audio.Media.ARTIST + " DESC";
Cursor cursor = contentResolver.query(uri, null, selection, null, sortOrder);
if (cursor != null && cursor.getCount() > 0) {
audioList.clear();
while (cursor.moveToNext()) {
Audio audio = new Audio();
String data = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA));
String title = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.TITLE));
String album = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM));
String artist = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST));
int albumId = cursor.getInt(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));
Bitmap thumbnail = null;
String albumArt = null;
Uri imageUri_t;
Cursor cursor1 = contentResolver.query(MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI,
new String[]{MediaStore.Audio.Albums._ID, MediaStore.Audio.Albums.ALBUM_ART},
MediaStore.Audio.Albums._ID + "=" + albumId, null, null);
while (cursor1.moveToNext()) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
Size thumbSize = new Size(100, 100);
try {
int thumbColumn = cursor1.getColumnIndexOrThrow(MediaStore.Audio.Albums._ID);
int _thumpId = cursor1.getInt(thumbColumn);
imageUri_t = ContentUris.withAppendedId(MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, _thumpId);
thumbnail = getContentResolver().loadThumbnail(imageUri_t, thumbSize, null);
} catch (IOException e) {
e.printStackTrace();
}
} else {
albumArt = cursor1.getString(cursor1.getColumnIndex(MediaStore.Audio.Albums.ALBUM_ART));
}
}
audio.setData(data);
audio.setTitle(title);
audio.setAlbum(album);
audio.setArtist(artist);
audio.setAlbumId(albumId);
audio.setAlbumArt(albumArt);
audio.setThumbnail(thumbnail);
audioList.add(audio);
}
}
cursor.close();
setAdapter();
}
And a part of MyAdapter:
#Override
public void onBindViewHolder(#NonNull MainHolder holder, int position) {
Audio audio = arrayList.get(position);
holder.txtTitle.setText("Title: " + audio.getTitle());
holder.txtAlbum.setText("Album: " + audio.getAlbum());
holder.txtArtist.setText("Artist: " + audio.getArtist());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
if (audio.getThumbnail() != null)
holder.img.setImageBitmap(audio.getThumbnail());
} else {
if (audio.getAlbumArt() != null) {
File imgFile = new File(audio.getAlbumArt());
if (imgFile.exists()) {
Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
holder.img.setImageBitmap(myBitmap);
}
}
}
}
First query on MediaStore.Audio.Media.ARTIST about fetch audio info from MediaStore.
There is a difference About fetch thumbnail of Audio file in android 10 (Q) and below.
So query for lower than Android 10 is like follow:
String albumArt = cursor1.getString(cursor1.getColumnIndex(MediaStore.Audio.Albums.ALBUM_ART));
You can get album art from ALBUM_ART column in MediaStore.Audio.Albums.
Then for Android 10 like follow this:
Query on MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI where albumId equals _ID column from MediaStore.Audio.Albums.
And load thumbnail from Content Resolver by image uri...
I hope it is useful ;)
I want to fetch contacts and store them to a list. I can see my contact names and phones in the listView but image view is empty for all contacts.
How can I get Images?
I have a Fragment with a listView to show contacts.
This is my main fragment:
private List<AddressBookContact> getContacts() {
List<AddressBookContact> list = new LinkedList<>();
LongSparseArray<AddressBookContact> array = new LongSparseArray<>();
long start = System.currentTimeMillis();
String[] projection = {
ContactsContract.Data.MIMETYPE,
ContactsContract.Data.CONTACT_ID,
ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Contactables.DATA,
ContactsContract.CommonDataKinds.Contactables.TYPE,
};
String selection = ContactsContract.Data.MIMETYPE + " in (?, ?)";
String[] selectionArgs = {
ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE,
ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE,
};
String sortOrder = ContactsContract.Contacts.SORT_KEY_ALTERNATIVE;
Uri uri = null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2) {
uri = ContactsContract.CommonDataKinds.Contactables.CONTENT_URI;
} else {
uri = ContactsContract.Data.CONTENT_URI;
}
// we could also use Uri uri = ContactsContract.Data.CONTENT_URI;
// ok, let's work...
Cursor cursor = getContext().getContentResolver().query(uri, projection, selection, selectionArgs, sortOrder);
final int mimeTypeIdx = cursor.getColumnIndex(ContactsContract.Data.MIMETYPE);
final int idIdx = cursor.getColumnIndex(ContactsContract.Data.CONTACT_ID);
final int nameIdx = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
final int dataIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Contactables.DATA);
final int typeIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Contactables.TYPE);
while (cursor.moveToNext()) {
long id = cursor.getLong(idIdx);
AddressBookContact addressBookContact = array.get(id);
if (addressBookContact == null) {
addressBookContact = new AddressBookContact(
id, cursor.getString(nameIdx), getResources(), openPhoto(idIdx));
array.put(id, addressBookContact);
list.add(addressBookContact);
}
int type = cursor.getInt(typeIdx);
String data = cursor.getString(dataIdx);
String mimeType = cursor.getString(mimeTypeIdx);
if (mimeType.equals(ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE)) {
// mimeType == ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE
addressBookContact.addEmail(type, data);
} else {
// mimeType == ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE
addressBookContact.addPhone(type, data);
}
}
cursor.close();
return list;
}
I want to make a WhatsApp call to a specific user. I tried this and it doesn't work:
Uri uri = Uri.parse("callto:" + phoneNUmber);
Intent i = new Intent(Intent.ACTION_CALL, uri);
i.setPackage("com.whatsapp");
startActivity(i);
I know how to create a WhatsApp message, the code is similar and it works:
Uri uri = Uri.parse("smsto:" + phoneNUmber);
Intent i = new Intent(Intent.ACTION_SENDTO, uri);
i.setPackage("com.whatsapp");
startActivity(i);
Simple solution is, Query ContactContract.Data for the _id and MIME type.
ContentResolver resolver = context.getContentResolver();
cursor = resolver.query(
ContactsContract.Data.CONTENT_URI,
null, null, null,
ContactsContract.Contacts.DISPLAY_NAME);
//Now read data from cursor like
while (cursor.moveToNext()) {
long _id = cursor.getLong(cursor.getColumnIndex(ContactsContract.Data._ID));
String displayName = cursor.getString(cursor.getColumnIndex(ContactsContract.Data.DISPLAY_NAME));
String mimeType = cursor.getString(cursor.getColumnIndex(ContactsContract.Data.MIMETYPE));
Log.d("Data", _id+ " "+ displayName + " " + mimeType );
}
The output will be like the following
12561 Snow vnd.android.cursor.item/vnd.com.whatsapp.profile
12562 Snow vnd.android.cursor.item/vnd.com.whatsapp.voip.call
Now save in DB or somewhere else only those _Ids whose MIME type is vnd.android.cursor.item/vnd.com.whatsapp.voip.call
And then you initiate Whatsapp call with those contacts like this way
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
// the _ids you save goes here at the end of /data/12562
intent.setDataAndType(Uri.parse("content://com.android.contacts/data/_id"),
"vnd.android.cursor.item/vnd.com.whatsapp.voip.call");
intent.setPackage("com.whatsapp");
startActivity(intent);
To make WhatsApp video call use below mime-string:
String mimeString = "vnd.android.cursor.item/vnd.com.whatsapp.video.call";
To make WhatsApp voice call use below mime-string:
String mimeString = "vnd.android.cursor.item/vnd.com.whatsapp.voip.call";
Use Below Code:
String displayName = null;
String name="ABC" // here you can give static name.
Long _id;
ContentResolver resolver = getApplicationContext().getContentResolver();
cursor = resolver.query(ContactsContract.Data.CONTENT_URI, null, null, null, ContactsContract.Contacts.DISPLAY_NAME);
while (cursor.moveToNext()) {
_id = cursor.getLong(cursor.getColumnIndex(ContactsContract.Data._ID));
displayName = cursor.getString(cursor.getColumnIndex(ContactsContract.Data.DISPLAY_NAME));
String mimeType = cursor.getString(cursor.getColumnIndex(ContactsContract.Data.MIMETYPE));
if (displayName.equals(name)) {
if (mimeType.equals(mimeString)) {
String data = "content://com.android.contacts/data/" + _id;
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_VIEW);
sendIntent.setDataAndType(Uri.parse(data), mimeString);
sendIntent.setPackage("com.whatsapp");
startActivity(sendIntent);
}
}
}
this code is to check number has whatsapp or not and make whatsapp audio and video call
first check wether number have whatsapp or not ...if you dont know
if rowContactId (return type of hasWhatsapp) is not equal to '0' then this number has whatsapp.
.
public String hasWhatsapp( getContactIDFromNumber(795486179).toString(),MAinactivity.this )
{
String rowContactId = null;
boolean hasWhatsApp;
String[] projection = new String[]{ContactsContract.RawContacts._ID};
String selection = ContactsContract.Data.CONTACT_ID + " = ? AND account_type IN (?)";
String[] selectionArgs = new String[]{contactID, "com.whatsapp"};
Cursor cursor = getContentResolver().query(ContactsContract.RawContacts.CONTENT_URI, projection, selection, selectionArgs, null);
if (cursor != null) {
hasWhatsApp = cursor.moveToNext();
if (hasWhatsApp) {
rowContactId = cursor.getString(0);
}
cursor.close();
}
return rowContactId;
}
public static int getContactIDFromNumber( contactNumber,Context context)
{
contactNumber = Uri.encode(contactNumber);
int phoneContactID = new Random().nextInt();
Cursor contactLookupCursor = context.getContentResolver().query(Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI,contactNumber),new String[] {ContactsContract.PhoneLookup.DISPLAY_NAME, ContactsContract.PhoneLookup._ID}, null, null, null);
while(contactLookupCursor.moveToNext())
{
phoneContactID = contactLookupCursor.getInt(contactLookupCursor.getColumnIndexOrThrow(ContactsContract.PhoneLookup._ID));
}
contactLookupCursor.close();
return phoneContactID;
}
//your number is support for whatsapp then come to here to make whatsapp call
// this is for whatsapp call
wtsapp_call.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
String mimeString = "vnd.android.cursor.item/vnd.com.whatsapp.voip.call";
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
//here you have to pass whatsApp contact number as contact_number ..
String name= getContactName( contact_number, MainActivity.this);
int whatsappcall=getContactIdForWhatsAppCall(name,MainActivity.this);
if (whatsappcall!=0) {
intent.setDataAndType(Uri.parse("content://com.android.contacts/data/" +whatsappcall),
"vnd.android.cursor.item/vnd.com.whatsapp.voip.call");
intent.setPackage("com.whatsapp");
startActivityForResult(intent, WHATSAPP_NUMMBER);
}
}
});
//for whatsapp video call
wtsapp_video.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v)
{
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
//here you have to pass whatsApp contact number as number..
String name= getContactName( number, MainActivity.this);
int videocall=getContactIdForWhatsAppVideoCall(name,MainActivity.this);
if (videocall!=0)
{
intent.setDataAndType(Uri.parse("content://com.android.contacts/data/" +videocall),
"vnd.android.cursor.item/vnd.com.whatsapp.video.call");
intent.setPackage("com.whatsapp");
startActivity(intent);
}
}
});
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;
}
public int getContactIdForWhatsAppCall(String name,Context context)
{
cursor = getContentResolver().query(
ContactsContract.Data.CONTENT_URI,
new String[]{ContactsContract.Data._ID},
ContactsContract.Data.DISPLAY_NAME + "=? and "+ContactsContract.Data.MIMETYPE+ "=?",
new String[] {name,"vnd.android.cursor.item/vnd.com.whatsapp.voip.call"},
ContactsContract.Contacts.DISPLAY_NAME);
if (cursor.getCount()>0)
{
cursor.moveToNext();
int phoneContactID= cursor.getInt(cursor.getColumnIndex(ContactsContract.Data._ID));
System.out.println("9999999999999999 name "+name+" id "+phoneContactID);
return phoneContactID;
}
else
{
System.out.println("8888888888888888888 ");
return 0;
}
}
public int getContactIdForWhatsAppVideoCall(String name,Context context)
{
Cursor cursor = getContentResolver().query(
ContactsContract.Data.CONTENT_URI,
new String[]{ContactsContract.Data._ID},
ContactsContract.Data.DISPLAY_NAME + "=? and "+ContactsContract.Data.MIMETYPE+ "=?",
new String[] {name,"vnd.android.cursor.item/vnd.com.whatsapp.video.call"},
ContactsContract.Contacts.DISPLAY_NAME);
if (cursor.getCount()>0)
{
cursor.moveToFirst();
int phoneContactID= cursor.getInt(cursor.getColumnIndex(ContactsContract.Data._ID));
return phoneContactID;
}
else
{
System.out.println("8888888888888888888 ");
return 0;
}
}
If we pass rawContactId, then we can use that to directly fetch the ID associated with the whatsapp call URI.
private void whatsAppCall(Context context, String rawContactId) {
try {
int id = whatsAppCallId(context, rawContactId);
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
String uriString = "content://com.android.contacts/data/" + id;
intent.setDataAndType(Uri.parse(uriString), "vnd.android.cursor.item/vnd.com.whatsapp.voip.call");
intent.setPackage("com.whatsapp");
startActivity(intent);
} catch (Exception e) {
Log.e(TAG, "whatsAppCall Exception: " + e);
}
}
private long whatsAppCallId(Context context, String rawContactId){
ContentResolver resolver = context.getContentResolver();
String selection = ContactsContract.Data.MIMETYPE + " = ? AND " + ContactsContract.Data.RAW_CONTACT_ID + " = ? ";
String[] selectionArgs = new String[] { "vnd.android.cursor.item/vnd.com.whatsapp.voip.call", rawContactId };
Cursor cursor = resolver.query(
ContactsContract.Data.CONTENT_URI,
null, selection, selectionArgs,
ContactsContract.Contacts.DISPLAY_NAME);
long _id=0;
while (cursor.moveToNext()) {
_id = cursor.getLong(cursor.getColumnIndex(ContactsContract.Data._ID));
String displayName = cursor.getString(cursor.getColumnIndex(ContactsContract.Data.DISPLAY_NAME));
String mimeType = cursor.getString(cursor.getColumnIndex(ContactsContract.Data.MIMETYPE));
Log.d(TAG, "Data: " + _id+ " "+ displayName + " " + mimeType );
}
return _id;
}
Answer provided by #Adnan Khan works in Android 11, but I wanted to provide the Kotlin version of his answer:
val resolver: ContentResolver = requireContext().contentResolver
val cursor: Cursor? = resolver.query(
ContactsContract.Data.CONTENT_URI,
null, null, null,
ContactsContract.Contacts.DISPLAY_NAME)
while(cursor!!.moveToNext()) {
val _id: Long = cursor.getLong(cursor.getColumnIndex(ContactsContract.Data._ID))
val displayName: String = cursor.getString(cursor.getColumnIndex(ContactsContract.Data.DISPLAY_NAME))
val mimeType: String = cursor.getString(cursor.getColumnIndex(ContactsContract.Data.MIMETYPE))
Log.i("Intents", "$_id $displayName $mimeType")
Now, the intent in Kotlin goes like this:
_id is the value you get from the previous routing
val intent = Intent()
intent.action = Intent.ACTION_VIEW
intent.setDataAndType(Uri.parse("content://com.android.contacts/data/_id"),
"vnd.android.cursor.item/vnd.com.whatsapp.voip.call")
intent.setPackage("com.whatsapp")
startActivity(intent)
Last but not least add the following to the AndroidManifest.xml:
<uses-permission
android:name="android.permission.CALL_PHONE"
androd:maxSdkVersion="30" />
<uses-permission
android:name="android.permission.READ_CONTACTS"
androd:maxSdkVersion="30" />
After this, you need to go to Settings -> Apps -> Select your app and mark the two permissions as allowed.
There should be a way that the app ask you the first time it is run, but that is another topic.
// first check wether number have whatsapp or not ...if you dont know
//if rowContactId (return type of hasWhatsapp) is not equal to '0' then this number has whatsapp..
public String hasWhatsapp( getContactIDFromNumber(795486179).toString(),MAinactivity.this )
{
String rowContactId = null;
boolean hasWhatsApp;
String[] projection = new String[]{ContactsContract.RawContacts._ID};
String selection = ContactsContract.Data.CONTACT_ID + " = ? AND account_type IN (?)";
String[] selectionArgs = new String[]{contactID, "com.whatsapp"};
Cursor cursor = getContentResolver().query(ContactsContract.RawContacts.CONTENT_URI, projection, selection, selectionArgs, null);
if (cursor != null) {
hasWhatsApp = cursor.moveToNext();
if (hasWhatsApp) {
rowContactId = cursor.getString(0);
}
cursor.close();
}
return rowContactId;
}
public static int getContactIDFromNumber( contactNumber,Context context)
{
contactNumber = Uri.encode(contactNumber);
int phoneContactID = new Random().nextInt();
Cursor contactLookupCursor = context.getContentResolver().query(Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI,contactNumber),new String[] {ContactsContract.PhoneLookup.DISPLAY_NAME, ContactsContract.PhoneLookup._ID}, null, null, null);
while(contactLookupCursor.moveToNext())
{
phoneContactID = contactLookupCursor.getInt(contactLookupCursor.getColumnIndexOrThrow(ContactsContract.PhoneLookup._ID));
}
contactLookupCursor.close();
return phoneContactID;
}
//your number is support for whatsapp then come to here to make whatsapp call
// this is for whatsapp call
wtsapp_call.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
String mimeString = "vnd.android.cursor.item/vnd.com.whatsapp.voip.call";
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
//here you have to pass whatsApp contact number as contact_number ..
String name= getContactName( contact_number, MainActivity.this);
int whatsappcall=getContactIdForWhatsAppCall(name,MainActivity.this);
if (whatsappcall!=0) {
intent.setDataAndType(Uri.parse("content://com.android.contacts/data/" +whatsappcall),
"vnd.android.cursor.item/vnd.com.whatsapp.voip.call");
intent.setPackage("com.whatsapp");
startActivityForResult(intent, WHATSAPP_NUMMBER);
}
}
});
//for whatsapp video call
wtsapp_video.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v)
{
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
//here you have to pass whatsApp contact number as number..
String name= getContactName( number, MainActivity.this);
int videocall=getContactIdForWhatsAppVideoCall(name,MainActivity.this);
if (videocall!=0)
{
intent.setDataAndType(Uri.parse("content://com.android.contacts/data/" +videocall),
"vnd.android.cursor.item/vnd.com.whatsapp.video.call");
intent.setPackage("com.whatsapp");
startActivity(intent);
}
}
});
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;
}
public int getContactIdForWhatsAppCall(String name,Context context)
{
cursor = getContentResolver().query(
ContactsContract.Data.CONTENT_URI,
new String[]{ContactsContract.Data._ID},
ContactsContract.Data.DISPLAY_NAME + "=? and "+ContactsContract.Data.MIMETYPE+ "=?",
new String[] {name,"vnd.android.cursor.item/vnd.com.whatsapp.voip.call"},
ContactsContract.Contacts.DISPLAY_NAME);
if (cursor.getCount()>0)
{
cursor.moveToNext();
int phoneContactID= cursor.getInt(cursor.getColumnIndex(ContactsContract.Data._ID));
System.out.println("9999999999999999 name "+name+" id "+phoneContactID);
return phoneContactID;
}
else
{
System.out.println("8888888888888888888 ");
return 0;
}
}
public int getContactIdForWhatsAppVideoCall(String name,Context context)
{
Cursor cursor = getContentResolver().query(
ContactsContract.Data.CONTENT_URI,
new String[]{ContactsContract.Data._ID},
ContactsContract.Data.DISPLAY_NAME + "=? and "+ContactsContract.Data.MIMETYPE+ "=?",
new String[] {name,"vnd.android.cursor.item/vnd.com.whatsapp.video.call"},
ContactsContract.Contacts.DISPLAY_NAME);
if (cursor.getCount()>0)
{
cursor.moveToFirst();
int phoneContactID= cursor.getInt(cursor.getColumnIndex(ContactsContract.Data._ID));
return phoneContactID;
}
else
{
System.out.println("8888888888888888888 ");
return 0;
}
}
iv_whatsapp_call.setOnClickListener {
// val dialIntent = Intent(Intent.ACTION_DIAL)
// dialIntent.data = Uri.parse("tel:" + et_whatsapp.text.toString())
// startActivity(dialIntent)
val mimeString = "vnd.android.cursor.item/vnd.com.whatsapp.voip.call"
val resolver: ContentResolver = applicationContext.contentResolver
val cursor: Cursor? = resolver.query(ContactsContract.Data.CONTENT_URI, null, null, null, ContactsContract.Contacts.DISPLAY_NAME)
while(cursor!!.moveToNext()) {
var Col_Index = cursor!!.getColumnIndex(ContactsContract.CommonDataKinds.Phone._ID)
val _id = cursor.getLong(Col_Index)
Col_Index = cursor!!.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)
var number = cursor.getString(Col_Index)
Col_Index = cursor!!.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)
val displayName = cursor.getString(Col_Index)
Col_Index = cursor!!.getColumnIndex(ContactsContract.CommonDataKinds.Phone.MIMETYPE)
val mimeType = cursor.getString(Col_Index)
// println("Data: " + _id.toString() + " ---" + displayName + "---" + number + "---" + mimeType )
var my_number = et_whatsapp.text.toString()
my_number = my_number.replace(" ","")
my_number = my_number.replace("+","")
if(number.isNullOrBlank() == false) {
// println("Number : " + number )
number = number.replace(" ", "")
number = number.replace("+", "")
// my_number.substring(1)
// println(">>" + my_number)
if (number.endsWith(my_number.substring(1) + "#s.whatsapp.net")){
if (mimeType.equals(mimeString)) {
val data = "content://com.android.contacts/data/$_id"
val sendIntent = Intent()
sendIntent.action = Intent.ACTION_VIEW
sendIntent.setDataAndType(Uri.parse(data), mimeString)
sendIntent.setPackage("com.whatsapp")
startActivity(sendIntent)
break;
}
}
}
}
}
I am new to Android and Java and this week I've been doing a self-taught crash course. So far what I've learned has not been too complicated as I've already built a number of years of coding experience. So, background history out of the way, onto my question.
The below code is two functions I wrote to take an image ID from a database and parse the correct Uri which I can then use to upload the photo to a website. So could you kind folks look over my code and let me know if I'm doing a terrible job or if I am heading in the right direction or even if there is a better/native way to do what I need.
Also, note: the below code does work. I just don't know if it is the right way to do it.
Thanks!
// Usage Map idPath = ImageIdPathFetcher.getRealIdPathFromID(getApplicationContext(), Integer.valueOf(image_id));
public static Map getRealIdPathFromID(Context context, Integer id) {
Map<String,String> idPath = new HashMap<String, String>();
Uri external_images_uri = MediaStore.Images.Media.getContentUri("external");
Uri internal_images_uri = MediaStore.Images.Media.getContentUri("internal");
// initialize uri
Uri uri = external_images_uri;
String ext_img_uri = external_images_uri.toString()+"/"+id;
String int_img_uri = internal_images_uri.toString()+"/"+id;
if(check_uri(context, ext_img_uri))
{
uri = Uri.parse(ext_img_uri);
}else if(check_uri(context, int_img_uri))
{
uri = Uri.parse(int_img_uri);
}else {
idPath.put("id", "");
idPath.put("path", "");
return idPath;
}
String[] proj = { Media.DATA, Media._ID };
Cursor cursor = context.getContentResolver().query(uri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(Media.DATA);
cursor.moveToFirst();
String filepath = cursor.getString(column_index);
idPath.put("id", id.toString());
idPath.put("path", filepath);
return idPath;
}
public static boolean check_uri(Context context, String uri)
{
try{
ContentResolver cr = context.getContentResolver();
String[] projection = {MediaStore.MediaColumns.DATA};
Cursor cur = cr.query(Uri.parse(uri), projection, null, null, null);
if(cur != null)
{
cur.moveToFirst();
String filePath = cur.getString(0);
if(! new File(filePath).exists()){
return false;
}
} else {
return false;
}
} catch (Exception e)
{
return false;
}
return true;
}
This is what I use
public static Uri getImageContentUri(Context context, File imageFile) {
String filePath = imageFile.getAbsolutePath();
Cursor cursor = context.getContentResolver().query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
new String[]{MediaStore.Images.Media._ID},
MediaStore.Images.Media.DATA + "=? ",
new String[]{filePath}, null);
if (cursor != null) {
try {
if (cursor.moveToFirst()) {
int id = cursor.getInt(cursor.getColumnIndex(MediaStore.MediaColumns._ID));
return Uri.withAppendedPath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, String.valueOf(id));
}
} finally {
cursor.close();
}
}
cursor = context.getContentResolver().query(
MediaStore.Images.Media.INTERNAL_CONTENT_URI,
new String[]{MediaStore.Images.Media._ID},
MediaStore.Images.Media.DATA + "=? ",
new String[]{filePath}, null);
if (cursor != null) {
try {
if (cursor.moveToFirst()) {
int id = cursor.getInt(cursor.getColumnIndex(MediaStore.MediaColumns._ID));
return Uri.withAppendedPath(MediaStore.Images.Media.INTERNAL_CONTENT_URI, String.valueOf(id));
}
} finally {
cursor.close();
}
}
return null;
}
It is possible to query both internal and external MediaStore database also with MergeCursor:
String myIdImgStr = "123"; // the unique ID of the image in the MediaStore
ContentResolver contentResolver = this.getContext().getContentResolver();
String [] proj = { MediaStore.Images.Media.DATA, MediaStore.Images.Media._ID };
MergeCursor cursor = new MergeCursor(new Cursor[] {
MediaStore.Images.Media.query(contentResolver,
Uri.parse(MediaStore.Images.Media.INTERNAL_CONTENT_URI + "/" + myIdImgStr),
proj),
MediaStore.Images.Media.query(contentResolver,
Uri.parse(MediaStore.Images.Media.EXTERNAL_CONTENT_URI + "/" + myIdImgStr),
proj)
});
if(cursor.getCount() == 1) {
cursor.moveToFirst();
String filepath = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
}
I have created a working ViewBinder to use with my simpleCursorAdapter, and all is functioning properly. The desired images display as they should,etc. But when I was testing my code, I put a log my in my viewbinder that displays the criteria for displaying the image. When I look at logCat, it shows two iterations of the results as shown below. (there are only five entries). Which would in turn create two iterations of my if statements and resulting image display. This isn't a problem with the display, but it would create some redundancy in that it would display the images in the listView twice.
LOG FILE:
columnIndex=1 categoryIdentifier = Supplier
columnIndex=1 categoryIdentifier = Customer
columnIndex=1 categoryIdentifier = Other
columnIndex=1 categoryIdentifier = Other
columnIndex=1 categoryIdentifier = Other
columnIndex=1 categoryIdentifier = Supplier
columnIndex=1 categoryIdentifier = Customer
columnIndex=1 categoryIdentifier = Other
columnIndex=1 categoryIdentifier = Other
columnIndex=1 categoryIdentifier = Other
The code to run the viewBinder is this:
CODE:
private void fillData() {
//The desired columns to be bound:
String[] from = new String[] { ContactsDB.COLUMN_CATEGORY, ContactsDB.COLUMN_LAST_NAME, ContactsDB.COLUMN_FIRST_NAME };
//The XML views that the data will be bound to:
int[] to = new int[] {R.id.contact_icon, R.id.label2, R.id.label};
getLoaderManager().initLoader(0, null, this);
adapter = new SimpleCursorAdapter(this, R.layout.contact_row, null, from, to, 0);
// Set the ViewBinder to alternate the image in the listView
adapter.setViewBinder(new SimpleCursorAdapter.ViewBinder() {
public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
// int viewId = view.getId();
int categoryIndex = cursor.getColumnIndexOrThrow(ContactsDB.COLUMN_CATEGORY);
if(columnIndex == categoryIndex)
{
String categoryIdentifier = cursor.getString(columnIndex);
//switch categoryIdentifier
if(categoryIdentifier.equalsIgnoreCase("Supplier")){
displayImage = (ImageView) view;
displayImage.setImageResource(R.drawable.supplier);
}
if(categoryIdentifier.equalsIgnoreCase("Other")){
displayImage = (ImageView) view;
displayImage.setImageResource(R.drawable.other);
}
Log.v("TEST COMPARISON", "columnIndex=" + columnIndex + " categoryIdentifier = " + categoryIdentifier);
return true;
}
return false;
}
});
setListAdapter(adapter);
} // end of fillData
// Sort the names by last name, then by first name
String orderBy = ContactsDB.COLUMN_LAST_NAME + " COLLATE NOCASE ASC"
+ "," + ContactsDB.COLUMN_FIRST_NAME + " COLLATE NOCASE ASC" ;
// Creates a new loader after the initLoader () call
#Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
//String[] projection = { ContactsDB.ROW_ID, ContactsDB.COLUMN_LAST_NAME, ContactsDB.COLUMN_FIRST_NAME };
String[] projection = { ContactsDB.ROW_ID, ContactsDB.COLUMN_CATEGORY, ContactsDB.COLUMN_LAST_NAME, ContactsDB.COLUMN_FIRST_NAME };
CursorLoader cursorLoader = new CursorLoader(this,
whateverContentProvider.CONTENT_URI, projection, null, null, orderBy);
return cursorLoader;
}
Anyone know why there would be this redundancy?
change your listview android:layout_height to match_parent