问题
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};
// }
}
}
回答1:
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;
}
}
回答2:
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);
}
}
来源:https://stackoverflow.com/questions/20694047/get-images-and-videos-from-android-phone-into-custom-gallery