I'm trying to create a custom gallery that allows users to pick from all the photos and videos contained on their Android device. I know how to create a gallery of just photos and just videos, but if I want to combine both, how can I do this?
I think the issue comes down to how I create my cursor. To select all videos, I created the cursor this way:
String[] videoParams = {MediaStore.Video.Media._ID,
MediaStore.Video.Media.DATA,
MediaStore.Video.Media.DATE_TAKEN,
MediaStore.Video.Thumbnails.DATA};
videocursor = getContentResolver().query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, videoParams, null, null, null);
If I want to query all the media files, not just video, what do I do?
This is what I tried, based off of: Custom Gallery with Images and Videos in android to select multiple items
String selectionMimeType = MediaStore.Files.FileColumns.MIME_TYPE + "=?";
String jpg_mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension("jpg");
String png_mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension("png");
String mp4_mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension("mp4");
String[] selectionArgs = new String[]{jpg_mimeType, png_mimeType, mp4_mimeType};
mediaCursor = getContentResolver().query(MediaStore.Files.getContentUri("internal"), null, selectionMimeType, selectionArgs, MediaStore.Files.FileColumns.DATE_ADDED);
This gives me the error java.lang.IllegalArgumentException: Cannot bind argument at index 3 because the index is out of range. The statement has 1 parameters at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:167)
Perhaps my approach is completely wrong, but I can't find any examples of custom android galleries using both images and videos, which is bizarre to me as this seems like it would be a common thing to create.
Here's all of my code, in case it's helpful:
public class GridViewCompatActivity extends Activity {
GridViewCompat gridView;
private static final String TAG = "GridViewCompatActivity";
Cursor videocursor;
Cursor mediaCursor;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_grid_view_compat);
gridView = (GridViewCompat) findViewById(R.id.gridView1);
// NOTE: We are using setChoiceMode, as I said, its a drop-in replacement
gridView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
gridView.setAdapter(new ImageAdapter(getApplicationContext()));
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> view, View arg1, int pos, long id) {
// We need to invalidate all views on 4.x versions
GridViewCompat gridView = (GridViewCompat) view;
gridView.invalidateViews();
}
});
findViewById(R.id.button1).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
SparseBooleanArray checkArray;
checkArray = gridView.getCheckedItemPositions();
String selectedPos = "Selected positions: ";
int count = checkArray.size();
for (int i = 0; i < count; i++) {
if (checkArray.valueAt(i))
selectedPos += checkArray.keyAt(i) + ",";
}
Intent intent = new Intent();
intent.putExtra("result", selectedPos);
setResult(Activity.RESULT_OK, intent);
finish();
}
});
}
public class ImageAdapter extends BaseAdapter {
private Context mContext;
public ImageAdapter(Context c) {
mContext = c;
}
public int getCount() {
Log.d(TAG, "number of media: " + Integer.toString(MediaStore.Files.FileColumns.DATA.length()));
int mediaParams = MediaStore.MediaColumns.DATA.length();
return mediaParams;
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
// create a new grid view item for each item referenced by the Adapter
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
CheckBox checkBox;
if (convertView == null) {
LayoutInflater layoutInflater = LayoutInflater.from(mContext);
convertView = layoutInflater.inflate(R.layout.grid_view_item, parent, false);
}
imageView = (ImageView) convertView.findViewById(R.id.imageView1);
checkBox = (CheckBox) convertView.findViewById(R.id.checkBox1);
GridViewCompat gvc = (GridViewCompat) parent;
if (gvc.getChoiceMode() == ListView.CHOICE_MODE_MULTIPLE) {
SparseBooleanArray checkArray;
checkArray = gvc.getCheckedItemPositions();
checkBox.setChecked(false);
if (checkArray != null) {
if (checkArray.get(position)) {
checkBox.setChecked(true);
}
}
}
// imageView.setImageResource(mThumbIds[position]);
Bitmap bmThumbnail;
Log.d(TAG, "position: " + position);
mediaCursor = getContentResolver().query(MediaStore.Files.getContentUri("internal"), null, selectionMimeType, selectionArgs, MediaStore.Files.FileColumns.DATE_ADDED);
Log.d(TAG, Integer.toString(mediaCursor.getCount()));
for (int i = 0; i < mediaCursor.getCount(); i++){
mediaCursor.moveToPosition(i);
Boolean isVideo = mediaCursor.getString(mediaCursor.getColumnIndex(MediaStore.Video.Thumbnails.DATA)).length() > 0;
Log.d(TAG, "isVideo: " + isVideo);
String mediaPath = "";
if(isVideo){
mediaPath = mediaCursor.getString(mediaCursor.getColumnIndex(MediaStore.Video.Thumbnails.DATA));
video_paths.add(mediaPath);
}else{
mediaPath = mediaCursor.getString(mediaCursor.getColumnIndex(MediaStore.Images.Media.DATA));
video_paths.add(mediaPath);
}
Log.d(TAG, "mediaPath: " +mediaPath);
}
mediaCursor.moveToPosition(position);
String video_path = mediaCursor.getString(mediaCursor.getColumnIndex(MediaStore.Video.Thumbnails.DATA));
Log.d(TAG, "video_path: " + video_path);
imageView.setImageBitmap(ThumbnailUtils.createVideoThumbnail(video_path, Thumbnails.MICRO_KIND));
return convertView;
}
ArrayList<String> video_paths = new ArrayList<String>();
String selectionMimeType = MediaStore.Files.FileColumns.MIME_TYPE + "=?";
String jpg_mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension("jpg");
String png_mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension("png");
String mp4_mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension("mp4");
String[] selectionArgs = new String[]{jpg_mimeType, png_mimeType, mp4_mimeType};
// String[] videoParams = {MediaStore.Video.Media._ID,
// MediaStore.Video.Media.DATA,
// MediaStore.Video.Media.DATE_TAKEN,
// MediaStore.Video.Thumbnails.DATA};
// }
}
}
public class GalleryFragment extends Fragment
{
private int count;
private Bitmap[] thumbnails;
private boolean[] thumbnailsselection;
private String[] arrPath;
private int[] typeMedia;
private ImageAdapter imageAdapter;
#SuppressLint("NewApi") #Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.gallery_gridview, container, false);
String[] columns = { MediaStore.Files.FileColumns._ID,
MediaStore.Files.FileColumns.DATA,
MediaStore.Files.FileColumns.DATE_ADDED,
MediaStore.Files.FileColumns.MEDIA_TYPE,
MediaStore.Files.FileColumns.MIME_TYPE,
MediaStore.Files.FileColumns.TITLE,
};
String selection = MediaStore.Files.FileColumns.MEDIA_TYPE + "="
+ MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE
+ " OR "
+ MediaStore.Files.FileColumns.MEDIA_TYPE + "="
+ MediaStore.Files.FileColumns.MEDIA_TYPE_VIDEO;
final String orderBy = MediaStore.Files.FileColumns.DATE_ADDED;
Uri queryUri = MediaStore.Files.getContentUri("external");
#SuppressWarnings("deprecation")
Cursor imagecursor = getActivity().managedQuery(queryUri,
columns,
selection,
null, // Selection args (none).
MediaStore.Files.FileColumns.DATE_ADDED + " DESC" // Sort order.
);
int image_column_index = imagecursor.getColumnIndex(MediaStore.Files.FileColumns._ID);
this.count = imagecursor.getCount();
this.thumbnails = new Bitmap[this.count];
this.arrPath = new String[this.count];
this.typeMedia = new int[this.count];
this.thumbnailsselection = new boolean[this.count];
for (int i = 0; i < this.count; i++) {
imagecursor.moveToPosition(i);
int id = imagecursor.getInt(image_column_index);
int dataColumnIndex = imagecursor.getColumnIndex(MediaStore.Files.FileColumns.DATA);
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inSampleSize = 4;
bmOptions.inPurgeable = true;
int type = imagecursor.getColumnIndex(MediaStore.Files.FileColumns.MEDIA_TYPE);
int t = imagecursor.getInt(type);
if(t == 1)
thumbnails[i] = MediaStore.Images.Thumbnails.getThumbnail(
getActivity().getContentResolver(), id,
MediaStore.Images.Thumbnails.MINI_KIND, bmOptions);
else if(t == 3)
thumbnails[i] = MediaStore.Video.Thumbnails.getThumbnail(
getActivity().getContentResolver(), id,
MediaStore.Video.Thumbnails.MINI_KIND, bmOptions);
arrPath[i]= imagecursor.getString(dataColumnIndex);
typeMedia[i] = imagecursor.getInt(type);
}
GridView imagegrid = (GridView) v.findViewById(R.id.PhoneImageGrid);
Button reSizeGallery = (Button) v.findViewById(R.id.reSizeGallery);
imageAdapter = new ImageAdapter();
imagegrid.setAdapter(imageAdapter);
imagecursor.close();
reSizeGallery.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
ChatViewerAdapter.ScreenResize(getActivity());
}
});
return v;//super.onCreateView(inflater, container, savedInstanceState);
}
public class ImageAdapter extends BaseAdapter {
private LayoutInflater mInflater;
public ImageAdapter() {
mInflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public int getCount() {
return count;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
#SuppressLint("NewApi") public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
Display display = getActivity().getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;
if (convertView == null) {
holder = new ViewHolder();
convertView = mInflater.inflate(
R.layout.gallery_view, null);
holder.imageview = (ImageView) convertView.findViewById(R.id.thumbImage);
holder.videoICON = (ImageView) convertView.findViewById(R.id.videoICON);
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
holder.imageview.getLayoutParams().height = height/6;
holder.imageview.getLayoutParams().width = width/4;
holder.imageview.setId(position);
if(typeMedia[position] == 1)
holder.videoICON.setVisibility(View.GONE);
else if(typeMedia[position] == 3)
holder.videoICON.setVisibility(View.VISIBLE);
holder.imageview.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
int id = v.getId();
Display display = ((WindowManager) getActivity().getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
int height = display.getHeight();
final int height_half = (int) (height/2.5);
RelativeLayout fragment_layout = (RelativeLayout) getActivity().findViewById(R.id.fragment_gallery);
fragment_layout.setVisibility(View.VISIBLE);
fragment_layout.getLayoutParams().height = height_half;
GalleryImageChooseFragment f_img_choose =new GalleryImageChooseFragment();
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
Bundle args = new Bundle();
args.putString("PATH", arrPath[id]);
f_img_choose.setArguments(args);
ft.show(f_img_choose);
ft.replace(R.id.fragment_tattle, f_img_choose);
ft.addToBackStack("f_img_choose");
ft.commit();
}
});
holder.imageview.setImageBitmap(thumbnails[position]);
holder.id = position;
return convertView;
}
}
class ViewHolder {
ImageView imageview;
ImageView videoICON;
int id;
}
}
Download source code form here (Get all videos from gallery android).
public void fn_video() {
int int_position = 0;
Uri uri;
Cursor cursor;
int column_index_data, column_index_folder_name,column_id,thum;
String absolutePathOfImage = null;
uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
String[] projection = {MediaStore.MediaColumns.DATA, MediaStore.Video.Media.BUCKET_DISPLAY_NAME,MediaStore.Video.Media._ID,MediaStore.Video.Thumbnails.DATA};
final String orderBy = MediaStore.Images.Media.DATE_TAKEN;
cursor = getApplicationContext().getContentResolver().query(uri, projection, null, null, orderBy + " DESC");
column_index_data = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
column_index_folder_name = cursor.getColumnIndexOrThrow(MediaStore.Video.Media.BUCKET_DISPLAY_NAME);
column_id = cursor.getColumnIndexOrThrow(MediaStore.Video.Media._ID);
thum = cursor.getColumnIndexOrThrow(MediaStore.Video.Thumbnails.DATA);
while (cursor.moveToNext()) {
absolutePathOfImage = cursor.getString(column_index_data);
Log.e("Column", absolutePathOfImage);
Log.e("Folder", cursor.getString(column_index_folder_name));
Log.e("column_id", cursor.getString(column_id));
Log.e("thum", cursor.getString(thum));
Model_Video obj_model = new Model_Video();
obj_model.setBoolean_selected(false);
obj_model.setStr_path(absolutePathOfImage);
obj_model.setStr_thumb(cursor.getString(thum));
al_video.add(obj_model);
}
}
This function will return arraylist of gallery images and videos in descending order. Just pass this function to adapter and show gallery stuff in recyclerview in kotlin.
#SuppressLint("Range")
fun getAllGalleryMedia(): ArrayList<Media> {
val result = ArrayList<Media>()
val projection = arrayOf(
MediaStore.Files.FileColumns._ID,
MediaStore.Files.FileColumns.DATA,
MediaStore.Files.FileColumns.DATE_ADDED,
MediaStore.Files.FileColumns.DISPLAY_NAME,
MediaStore.Files.FileColumns.MEDIA_TYPE,
MediaStore.Files.FileColumns.MIME_TYPE,
MediaStore.Files.FileColumns.TITLE
)
val selection = (MediaStore.Files.FileColumns.MEDIA_TYPE + "="
+ MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE
+ " OR "
+ MediaStore.Files.FileColumns.MEDIA_TYPE + "="
+ MediaStore.Files.FileColumns.MEDIA_TYPE_VIDEO)
val queryUri = MediaStore.Files.getContentUri("external")
Handler(Looper.getMainLooper()).post {
val cursorLoader = CursorLoader(
context,
queryUri,
projection,
selection,
null,
MediaStore.Files.FileColumns.DATE_ADDED + " DESC"
)
val cursor: Cursor? = cursorLoader.loadInBackground()
if (cursor != null) {
while (cursor.moveToNext()) {
val id = cursor.getLong(cursor.getColumnIndex(MediaStore.Files.FileColumns._ID))
val displayName =
cursor.getString(cursor.getColumnIndex(MediaStore.Files.FileColumns.DISPLAY_NAME))
val imagePath =
cursor.getString(cursor.getColumnIndex(MediaStore.Files.FileColumns.DATA))
val dateAdded =
cursor.getString(cursor.getColumnIndex(MediaStore.Files.FileColumns.DATE_ADDED))
val mimeType =
cursor.getString(cursor.getColumnIndex(MediaStore.Files.FileColumns.MIME_TYPE))
result.add(Media(id, displayName, imagePath, dateAdded, mimeType))
}
cursor.close()
}
}
return result
}
This is model class,you can modify according to your needs.
class Media:java.io.Serializable{
var id:Long=0
var displayName:String=""
var imagePath:String=""
var dateAdded:String=""
var mimeType:String=""
var isSelected:Boolean = false
constructor(){
// empty constructor
}
constructor(
id: Long,
displayName: String,
imagePath: String,
dateAdded: String,
mimeType: String
){
this.id = id
this.displayName = displayName
this.imagePath = imagePath
this.dateAdded = dateAdded
this.mimeType = mimeType
}}
Related
I have a problem with retrieving albumArt and setting that art to ImageView using AsyncTask in cursor adapter.
When I open my app it looks like this:
Then I scroll down the list and everything is fine(but also if I scroll list not very fast):
Then I scroll list back to the very beggining(not fast) and it looks fine as well:
Probably I do something wrong, I think, so I have question:
Is it possible somehow to solve that problem, I already tried a lot of different ways on how to implement AsyncTask and make it works fine, but in the end of the day it looks always the same.
Below is code for cursor adapter:
public class AllSongsCursorAdapter extends CursorAdapter {
public AllSongsCursorAdapter(Context context, Cursor cursor) {
super(context, cursor, 0);
}
public boolean isCheckBoxVisible;
private AddToFavouritesArray favouritesArray = AddToFavouritesArray.getInstance();
private static class ViewHolder {
CheckBox checkBox;
TextView title;
TextView artist;
ImageView albumArt;
private ViewHolder(View view) {
checkBox = (CheckBox) view.findViewById(R.id.favouritesCheckBox);
title = (TextView) view.findViewById(R.id.title);
artist = (TextView) view.findViewById(R.id.artist);
albumArt = (ImageView) view.findViewById(R.id.albumArt);
}
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup viewGroup) {
View view = LayoutInflater.from(context).inflate(R.layout.song_item, viewGroup, false);
ViewHolder viewHolder = new ViewHolder(view);
view.setTag(viewHolder);
return view;
}
#Override
public void bindView(View view, Context context, final Cursor cursor) {
final ViewHolder viewHolder = (ViewHolder) view.getTag();
if (isCheckBoxVisible) {
viewHolder.checkBox.setVisibility(View.VISIBLE);
} else {
viewHolder.checkBox.setVisibility(View.GONE);
}
final int position = cursor.getPosition();
viewHolder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if (b) {
favouritesArray.integerArray.add(position);
} else {
favouritesArray.integerArray.remove(Integer.valueOf(position));
}
}
});
int songTitle = cursor.getColumnIndex(MediaStore.Audio.Media.TITLE);
int songArtist = cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST);
String currentTitle = cursor.getString(songTitle);
String currentArtist = cursor.getString(songArtist);
viewHolder.title.setText(currentTitle);
viewHolder.artist.setText(currentArtist);
//__________________________ALBUM_ART_______________________________________________________
viewHolder.albumArt.setTag(cursor.getPosition());
new AsyncTask<ViewHolder, Void, Bitmap>(){
private ViewHolder viewHolder;
#Override
protected Bitmap doInBackground(ViewHolder... viewHolders) {
viewHolder = viewHolders[0];
int id = cursor.getColumnIndex(MediaStore.Audio.Media._ID);
long songId = cursor.getLong(id);
Bitmap albumArt = getAlbumId(context, songId);
return albumArt;
}
#Override
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
if(bitmap != null) {
viewHolder.albumArt.setImageBitmap(bitmap);
}else{
viewHolder.albumArt.setImageResource(R.drawable.placeholder);
}
}
}.execute(viewHolder);
}
private Bitmap getAlbumId(Context context, long id) {
Bitmap albumArt = null;
String selection = MediaStore.Audio.Media._ID + " = " + id + "";
Cursor cursor = context.getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, new String[]{
MediaStore.Audio.Media._ID, MediaStore.Audio.Media.ALBUM_ID},
selection, null, null);
if (cursor.moveToFirst()) {
long albumId = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));
albumArt = getAlbumArt(context, albumId);
}
cursor.close();
return albumArt;
}
private Bitmap getAlbumArt(Context context, long albumId) {
Bitmap albumArt = null;
String selection = MediaStore.Audio.Albums._ID + " = " + albumId + "";
Cursor cursor = context.getContentResolver().query(MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, null, selection, null, null);
if (cursor.moveToFirst()) {
int art = cursor.getColumnIndex(MediaStore.Audio.Albums.ALBUM_ART);
String currentArt = cursor.getString(art);
albumArt = BitmapFactory.decodeFile(currentArt);
}
cursor.close();
return albumArt;
}
}
And yes, sure, without AsyncTask everything works fine except scrolling is very slow.
Thank you in advance!
EDIT
In the end of the day, that's how it works. Thank you very much # Orest Savchak, my up-vote and acceptance for your answer. Thanks a lot.
//__________________________ALBUM_ART_______________________________________________________
int id = cursor.getColumnIndex(MediaStore.Audio.Media._ID);
long songId = cursor.getLong(id);
String string = getAlbumArtPath(context, songId);
if(string!=null) {
Picasso.with(context)
.load(new File(string))
.into(viewHolder.albumArt);
}else{
viewHolder.albumArt.setImageResource(R.drawable.placeholder);
}
}
private String getAlbumArtPath(Context context, long id) {
String selection = MediaStore.Audio.Media._ID + " = " + id + "";
Cursor cursor = context.getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, new String[]{
MediaStore.Audio.Media._ID, MediaStore.Audio.Media.ALBUM_ID},
selection, null, null);
if (cursor.moveToFirst()) {
long albumId = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));
return getAlbumArt(context, albumId);
}
cursor.close();
return null;
}
private String getAlbumArt(Context context, long albumId) {
String selection = MediaStore.Audio.Albums._ID + " = " + albumId + "";
Cursor cursor = context.getContentResolver().query(MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, null, selection, null, null);
if (cursor.moveToFirst()) {
int art = cursor.getColumnIndex(MediaStore.Audio.Albums.ALBUM_ART);
return cursor.getString(art);
}
cursor.close();
return null;
}
You should manage your tasks by yourself. Your views are recycled, so, you have one view for different rows, it causes a problem. Most of project use some libraries, that do it automatically for you - much easier, e.g Picasso
Picasso.with(context).load(new File(getAlbumArtPath(context, songId))).into(viewHolder.albumArt);
private String getAlbumArtPath(Context context, long id) {
String selection = MediaStore.Audio.Media._ID + " = " + id + "";
Cursor cursor = context.getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, new String[]{
MediaStore.Audio.Media._ID, MediaStore.Audio.Media.ALBUM_ID},
selection, null, null);
if (cursor.moveToFirst()) {
long albumId = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));
return getAlbumArt(context, albumId);
}
cursor.close();
return null;
}
private String getAlbumArt(Context context, long albumId) {
String selection = MediaStore.Audio.Albums._ID + " = " + albumId + "";
Cursor cursor = context.getContentResolver().query(MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, null, selection, null, null);
if (cursor.moveToFirst()) {
int art = cursor.getColumnIndex(MediaStore.Audio.Albums.ALBUM_ART);
return cursor.getString(art);
}
cursor.close();
return null;
}
I'm retrieving all contacts from both Google accounts and the phone.
I don't understand why pics are right for some and wrong for others.
Thanks a lot advance for any help.
This is my code,
List<AddressBookContact> list = new LinkedList<>();
LongSparseArray<AddressBookContact> array = new LongSparseArray<>();
String[] projection = {
ContactsContract.Data.MIMETYPE,
ContactsContract.Data.CONTACT_ID,
ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.Contacts.PHOTO_THUMBNAIL_URI,
ContactsContract.CommonDataKinds.Contactables.DATA,
ContactsContract.CommonDataKinds.Contactables.TYPE,
ContactsContract.RawContacts.ACCOUNT_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.Data.CONTENT_URI;
}
assert uri != null;
Cursor cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, sortOrder);
assert cursor != null;
final int idIdx = cursor.getColumnIndex(ContactsContract.Data.CONTACT_ID);
final int nameIdx = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
final int picIdx = cursor.getColumnIndex(ContactsContract.Data.PHOTO_THUMBNAIL_URI);
final int dataIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Contactables.DATA);
final int typeIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Contactables.TYPE);
//final int typeDir = cursor.getColumnIndex(ContactsContract.Directory.ACCOUNT_TYPE);
I loop across the cursor and do some filters to avoid some duplicates
The idea is to gather same contact info under a same contact (object)
while (cursor.moveToNext()) {
long id = cursor.getLong(idIdx);
AddressBookContact addressBookContact = array.get(id);
//if(!cursor.getString(cursor.getColumnIndex(ContactsContract.RawContacts.ACCOUNT_TYPE)).equals("com.google")){
//lastName = cursor.getString(nameIdx);
if(!lastName.toLowerCase().contains(cursor.getString(nameIdx).toLowerCase())){
if(!cursor.getString(nameIdx).toLowerCase().contains("unsub") && !cursor.getString(nameIdx).toLowerCase().contains("noreply")) {
if (!StringUtils.isEmailValid(cursor.getString(nameIdx).toLowerCase())) {
lastName = cursor.getString(nameIdx);
if (addressBookContact == null) {
addressBookContact = new AddressBookContact(id, cursor.getString(nameIdx), context.getResources());
addressBookContact.setImagepath(cursor.getString(picIdx));
array.put(id, addressBookContact);
list.add(addressBookContact);
addressBookContact.setId(id);
}
int type = cursor.getInt(typeIdx);
String data = cursor.getString(dataIdx);
addressBookContact.addEmail(type, data);
}
}
}
else{
if(addressBookContact != null){
int type = cursor.getInt(typeIdx);
String data = cursor.getString(dataIdx);
addressBookContact.addEmail(type, data);
}
}
//}
}
cursor.close();
return list;
}
Based on this, I create an object Contact which is retrieved within a Viewholder
#Override
public void onBindViewHolder(MyContactListViewHolder holder, int position) {
String imagepath = mainInfo.get(position).getImagepath();
if (imagepath != null && !imagepath.isEmpty()) {
ImageView imageView = (ImageView)holder.itemView.findViewById(R.id.imageview_contact_picture);
imageView.setImageURI(Uri.parse(imagepath));
}
else{
String firstLetter = mainInfo.get(position).getName().substring(0,1).toUpperCase();
TextDrawable drawable = TextDrawable.builder()
.buildRound(firstLetter, 0xff3fbfe8);
ImageView image = (ImageView) holder.itemView.findViewById(R.id.imageview_contact_no_picture);
image.setVisibility(View.VISIBLE);
image.setImageDrawable(drawable);
}
holder.textViewShowName.setText(mainInfo.get(position).getName());
}
Code for MyContactListViewHolder
class MyContactListViewHolder extends RecyclerView.ViewHolder{
ImageView imageViewUserImage;
TextView textViewShowName;
MyContactListViewHolder(View itemView) {
super(itemView);
textViewShowName = (TextView) itemView.findViewById(R.id.textview_contact_name);
imageViewUserImage = (ImageView) itemView.findViewById(R.id.imageview_contact_picture);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
MyBottomSheetDialogFragment bottomSheetDialogFragment = MyBottomSheetDialogFragment.newInstance();
Bundle bundle = new Bundle();
bundle.putParcelable("contact", mainInfo.get(getAdapterPosition()));
bottomSheetDialogFragment.setArguments(bundle);
bottomSheetDialogFragment.show(fragmentManager, null);
}
});
}
}
#Override
public MyContactListViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.contacts_list_item, parent, false);
return new MyContactListViewHolder(v);
}
Don't use findViewById in the onBindViewHolder method. Do it in MyContactListViewHolder (which you are already doing).
Try the following code,
#Override
public void onBindViewHolder(MyContactListViewHolder holder, int position) {
String imagepath = mainInfo.get(position).getImagepath();
if (imagepath != null && !imagepath.isEmpty()) {
holder.imageViewUserImage.setImageURI(Uri.parse(imagepath));
} else{
String firstLetter = mainInfo.get(position).getName().substring(0,1).toUpperCase();
TextDrawable drawable = TextDrawable.builder().buildRound(firstLetter, 0xff3fbfe8);
holder.imageViewUserImage.setVisibility(View.VISIBLE);
holder.imageViewUserImage.setImageDrawable(drawable);
}
holder.textViewShowName.setText(mainInfo.get(position).getName());
}
I am trying to display video files in listview from folder 'xyz' on sdcard, i have successfully displayed but problem is that it displays all video files stored on sdcard even out of folder 'abc' actually i want only video files stored in folder 'xyz' to be displayed. I am googling since 4 days but didn't find any solution for that. My code is that is showing all videos and working perfectly :
private Cursor videocursor;
private int video_column_index;
ListView videolist;
int count;
String[] thumbColumns = null ;
File videoFiles;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init_phone_video_grid();
#SuppressWarnings("deprecation")
private void init_phone_video_grid() {
System.gc();
String[] proj = { MediaStore.Video.Media._ID,
MediaStore.Video.Media.DATA,
MediaStore.Video.Media.DISPLAY_NAME,
MediaStore.Video.Media.SIZE };
videocursor = managedQuery( MediaStore.Video.Media.EXTERNAL_CONTENT_URI,proj,
null, null,null);
count = videocursor.getCount();
videolist = (ListView) findViewById(R.id.list);
videolist.setAdapter(new VideoAdapter(getApplicationContext()));
videolist.setOnItemClickListener(videogridlistener);
}
private OnItemClickListener videogridlistener = new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position,
long id) {
System.gc();
video_column_index = videocursor
.getColumnIndexOrThrow(MediaStore.Video.Media.DATA);
videocursor.moveToPosition(position);
String filename = videocursor.getString(video_column_index);
Intent intent = new Intent(MainActivity.this, ViewVideo.class);
intent.putExtra("videofilename", filename);
startActivity(intent);
}
};
public class VideoAdapter extends BaseAdapter {
private Context vContext;
public VideoAdapter(Context c) {
vContext = c;
}
public int getCount() {
return count;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
System.gc();
ViewHolder holder;
String id = null;
convertView = null;
if (convertView == null) {
convertView = LayoutInflater.from(vContext).inflate(R.layout.listitem, parent, false);
holder = new ViewHolder();
holder.txtTitle = (TextView) convertView.findViewById(R.id.txtTitle);
holder.txtSize = (TextView) convertView.findViewById(R.id.txtSize);
holder.thumbImage = (ImageView) convertView.findViewById(R.id.imgIcon);
video_column_index = videocursor.getColumnIndexOrThrow(MediaStore.Video.Media.DISPLAY_NAME);
videocursor.moveToPosition(position);
id = videocursor.getString(video_column_index);
video_column_index = videocursor.getColumnIndexOrThrow(MediaStore.Video.Media.SIZE);
videocursor.moveToPosition(position);
// id += " Size(KB):" + // videocursor.getString(video_column_index);
holder.txtTitle.setText(id);
holder.txtSize.setText(" Size(KB):" + videocursor.getString(video_column_index));
String[] proj = { MediaStore.Video.Media._ID,
MediaStore.Video.Media.DISPLAY_NAME,
MediaStore.Video.Media.DATA };
#SuppressWarnings("deprecation")
Cursor cursor = managedQuery(
MediaStore.Video.Media.EXTERNAL_CONTENT_URI, proj,
MediaStore.Video.Media.DISPLAY_NAME + "=?",
new String[] { id }, null);
cursor.moveToFirst();
long ids = cursor.getLong(cursor.getColumnIndex(MediaStore.Video.Media._ID));
ContentResolver crThumb = getContentResolver();
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 1;
Bitmap curThumb = MediaStore.Video.Thumbnails.getThumbnail(
crThumb, ids, MediaStore.Video.Thumbnails.MICRO_KIND,
options);
holder.thumbImage.setImageBitmap(curThumb);
curThumb = null;
}
return convertView;
}
}
static class ViewHolder {
TextView txtTitle;
TextView txtSize;
ImageView thumbImage;
}
Try this
public static final String[] VIDEO_PROJECTION = {MediaStore.Video.Media._ID, MediaStore.Video.Media.TITLE,
MediaStore.Video.Media.DATA};
public static final Uri VIDEO_SOURCE_URI = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
Querying the data using the content resolver
CursorLoader cursorLoader = new CursorLoader(getActivity(), VIDEO_SOURCE_URI, VIDEO_PROJECTION, MediaStore.Video.Media.DATA + " like ? ", new String[]{"%FOLDER_NAME%"},
MediaStore.Video.Media.DATA + " COLLATE NOCASE ASC;");
It retrievers all the video files from the FOLDER_NAME. Since there can be one or more folders with a name so it is better to provide absolute path.
hi guys i am making an android application IN which i have to display all the video contents of the sd card (album wise).....it means when WE WILL LOAD THE APPLICATION only the names of albums should be displayED.... AND when we click on the particular album ITS VIDEOS FILES SHOULD BE DISPLAYED................... i have been able to display the album names BUT THE PROBLEM IS THAT there is duplicate album names (i.e. IF TWO VIDEO files are of same album) then two different albums are being displaying...........so i want all the videos of same album should be in one "album name"........... and on the click of that album name "all its video contents should be displayed"
any help will be appreciated below is the main class (AlbumVideo.class)
public class AlbumVideo extends Activity {
private Cursor audiocursor;
private int audio_column_index;
ListView audiolist;
int count;
int album=1;
int dura;
int i1 =R.drawable.ic_launcher;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.imagexml1);
init_phone_videos_grid();
}
#SuppressWarnings("deprecation")
private void init_phone_videos_grid() {
System.gc();
final String[] projection = new String[] {
MediaStore.Video.VideoColumns.ALBUM };
final String sortOrder = VideoColumns.ALBUM + " COLLATE LOCALIZED ASC";
audiocursor = managedQuery(MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
projection, null, null, sortOrder);
count = audiocursor.getCount();
audiolist = (ListView) findViewById(R.id.PhoneVideo);
audiolist.setAdapter(new AudioAdapter(getApplicationContext()));
audiolist.setOnItemClickListener(videogridlistener);
}
private OnItemClickListener videogridlistener = new OnItemClickListener() {
#SuppressWarnings("rawtypes")
public void onItemClick(AdapterView parent, View v, int position,
long id) {
System.gc();
audio_column_index = audiocursor
.getColumnIndexOrThrow(MediaStore.Video.VideoColumns.ALBUM);
audiocursor.moveToPosition(position);
String filename = audiocursor.getString(audio_column_index);
Intent intent = new Intent(AlbumVideo.this,
AlbumVideoDetail.class);
intent.putExtra("albumfilename",filename);
intent.putExtra("album",album);
startActivity(intent);
}
};
public class AudioAdapter extends BaseAdapter
{
private Context vContext;
CheckBox cb;
int position=0;
int check=0;
String a[]=new String[count];
public AudioAdapter(Context c) {
vContext = c;
}
public int getCount() {
return count;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
System.gc();
LayoutInflater inflater = getLayoutInflater();
View row;
row = inflater.inflate(R.layout.list_item1, parent, false);
final Button title = (Button) row.findViewById(R.id.button);
title.setTextColor(Color.parseColor("#000000"));
if (convertView == null) {
audio_column_index =audiocursor.getColumnIndexOrThrow(MediaStore.Video.VideoColumns.ALBUM );
audiocursor.moveToPosition(position);
String TITLE = audiocursor.getString(audio_column_index);
String a[]=new String[count];
Toast.makeText(AlbumVideo.this, "music will be available shortly"+TITLE, Toast.LENGTH_LONG).show();
title.setText(TITLE);
}
return (row);
}
}
}
and the second class to display the songs of the particular album is ("AlbumVideoDetail.class")
public class AlbumVideoDetail extends Activity {
private Cursor videocursor;
private int video_column_index;
ListView videolist;
int count;
String title=null;
String desc=null;
int dura;
int i1 =R.drawable.ic_launcher;
String filename;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.imagexml);
Intent i = getIntent();
Bundle extras = i.getExtras();
filename = extras.getString("albumfilename");
// String filename1 = filename.substring(filename.indexOf("sdcard"),filename.length());
// String filename2= filename1.substring(7);
Toast.makeText(AlbumVideoDetail.this, "music will be available shortly"+filename, Toast.LENGTH_LONG).show();
init_phone_videos_grid();
}
#SuppressWarnings("deprecation")
private void init_phone_videos_grid() {
System.gc();
String[] proj = { MediaStore.Video.Media.DATA,
MediaStore.Video.Media._ID, MediaStore.Video.Media.TITLE,
MediaStore.Video.Media.DISPLAY_NAME,
MediaStore.Video.Media.MIME_TYPE,
MediaStore.Video.Media.DURATION,
MediaStore.Video.Media.SIZE,};
String where = android.provider.MediaStore.Video.Media.ALBUM + "=?";
String whereVal[] = { filename };
String orderBy = android.provider.MediaStore.Video.Media.TITLE;
videocursor = managedQuery(MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
proj, where, whereVal, orderBy);
count = videocursor.getCount();
videolist = (ListView) findViewById(R.id.PhoneVideoList);
videolist.setAdapter(new VideoAdapter(getApplicationContext()));
}
public class VideoAdapter extends BaseAdapter {
private Context vContext;
CheckBox cb;
int position=0;
int check=0;
public VideoAdapter(Context c) {
vContext = c;
}
public int getCount() {
return count;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
System.gc();
LayoutInflater inflater = getLayoutInflater();
View row;
row = inflater.inflate(R.layout.list_item2, parent, false);
final TextView title = (TextView) row.findViewById(R.id.title);
TextView desc = (TextView) row.findViewById(R.id.desc);
TextView dura = (TextView) row.findViewById(R.id.duration);
title.setTextColor(Color.parseColor("#000000"));
desc.setTextColor(Color.parseColor("#000000"));
dura.setTextColor(Color.parseColor("#000000"));
if (convertView == null) {
video_column_index =videocursor
.getColumnIndexOrThrow(MediaStore.Video.Media.DISPLAY_NAME);
videocursor.moveToPosition(position);
final String TITLE = videocursor.getString(video_column_index);
title.setText(TITLE);
video_column_index = videocursor
.getColumnIndexOrThrow(MediaStore.Video.Media.SIZE);
videocursor.moveToPosition(position);
String DESC= videocursor.getString(video_column_index);
int desd=Integer.parseInt(DESC);
int kb = (int) ((desd / 1000) % 1000);
int mb = (int) ((desd / 1000) / 1000);
String KB=Integer.toString(kb);
String MB=Integer.toString(mb);
String DESC1 = MB + "." + KB +"mb";
desc.setText(DESC1);
video_column_index = videocursor
.getColumnIndexOrThrow(MediaStore.Video.Media.DURATION);
videocursor.moveToPosition(position);
String DURA= videocursor.getString(video_column_index);
int duro = Integer.parseInt(DURA);
int seconds = (int) ((duro / 1000) % 60);
int minutes = (int) ((duro / 1000) / 60);
String secs=Integer.toString(seconds);
String mins=Integer.toString(minutes);
String DURA1 = mins + ":" + secs;
dura.setText(DURA1);
video_column_index = videocursor
.getColumnIndexOrThrow(MediaStore.Video.Media.DATA);
videocursor.moveToPosition(position);
final String filename = videocursor.getString(video_column_index);
} return (row);
}
}
}
wow after so much time spent on the internet at last found the solution for it !!!!!!! it an easy n very short step .,][.....i hope it will be helpful to someone ..........
private void init_phone_videos_grid() {
System.gc();
String[] proj = { MediaStore.Video.Media.DATA,
MediaStore.Video.Media._ID, MediaStore.Video.Media.TITLE,
MediaStore.Video.Media.DISPLAY_NAME,
MediaStore.Video.Media.MIME_TYPE,
MediaStore.Video.Media.DURATION,
MediaStore.Video.Media.SIZE,};
String where = android.provider.MediaStore.Video.Media.ALBUM + "=?";
String whereVal[] = { filename };
String orderBy = android.provider.MediaStore.Video.Media.TITLE;
videocursor = managedQuery(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, "DISTINCT "
+proj, where, whereVal, orderBy);
count = videocursor.getCount();
videolist = (ListView) findViewById(R.id.PhoneVideoList);
videolist.setAdapter(new VideoAdapter(getApplicationContext()));
}
just to add the word "distinct" in the class "album detail"....n it will sort d query according to yourt requirement....
Change the following:
final String[] projection = new String[] {MediaStore.Video.VideoColumns.ALBUM };
into
final String[] projection = new String[]{ "DISTINCT " +MediaStore.Video.VideoColumns.ALBUM};
Actually I tried with this coding it's working fine.i.e., showing all the images perfectly in emulator but coming to mobile it showing repeatedly the same image. I have attached the adapter class also
File file[] = Environment.getExternalStorageDirectory().listFiles();
String strFile = "";
for (int i = 0; i < file.length; i++) {
strFile += file[i].getAbsolutePath() + " :: ";
System.out.println("\n");
}
Log.i("test", strFile);
String[] img = { MediaStore.Images.Thumbnails._ID };
imagecursor = managedQuery(
MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, img, null,
null, MediaStore.Images.Thumbnails.IMAGE_ID + "");
image_column_index = imagecursor
.getColumnIndexOrThrow(MediaStore.Images.Thumbnails._ID);
count = imagecursor.getCount();
imagegrid = (ListView) findViewById(R.id.PhoneImageGrid);
imagegrid.setAdapter(new ImageAdapter(getApplicationContext()));
imagegrid.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position,
long id) {
System.gc();
String[] proj = { MediaStore.Images.Media.DATA };
actualimagecursor = managedQuery(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, proj,
null, null, null);
actual_image_column_index = actualimagecursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
actualimagecursor.moveToPosition(position);
String i = actualimagecursor
.getString(actual_image_column_index);
System.gc();
Intent intent = new Intent(getApplicationContext(),
ViewImage.class);
intent.putExtra("filename", i);
startActivity(intent);
}
});
}
Adapter Class:
public class ImageAdapter extends BaseAdapter {
private Context mContext;
public ImageAdapter(Context c) {
mContext = c;
}
public int getCount() {
return count;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
System.gc();
ImageView i = new ImageView(mContext.getApplicationContext());
if (convertView == null) {
imagecursor.moveToPosition(position);
int id = imagecursor.getInt(image_column_index);
i.setImageURI(Uri.withAppendedPath(
MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, ""
+ id));
i.setScaleType(ImageView.ScaleType.CENTER_CROP);
i.setLayoutParams(new GridView.LayoutParams(92, 92));
} else {
i = (ImageView) convertView;
}
return i;