下面列出了怎么用android.provider.MediaStore.Video的API类实例代码及写法,或者点击链接到github查看源代码。
@WorkerThread
private @NonNull List<Media> getMediaInBucket(@NonNull Context context, @NonNull String bucketId) {
if (!Permissions.hasAll(context, Manifest.permission.READ_EXTERNAL_STORAGE)) {
return Collections.emptyList();
}
List<Media> images = getMediaInBucket(context, bucketId, Images.Media.EXTERNAL_CONTENT_URI, true);
List<Media> videos = getMediaInBucket(context, bucketId, Video.Media.EXTERNAL_CONTENT_URI, false);
List<Media> media = new ArrayList<>(images.size() + videos.size());
media.addAll(images);
media.addAll(videos);
Collections.sort(media, (o1, o2) -> Long.compare(o2.getDate(), o1.getDate()));
return media;
}
private void saveVideo()
{
if (mVideoFileDescriptor == null)
{
long duration = SystemClock.uptimeMillis() - mRecordingStartTime;
if (duration > 0)
{
//
} else
{
Log.w(TAG, "Video duration <= 0 : " + duration);
}
mCurrentVideoValues.put(Video.Media.SIZE, new File(mCurrentVideoFilename).length());
mCurrentVideoValues.put(Video.Media.DURATION, duration);
getServices().getMediaSaver().addVideo(mCurrentVideoFilename,
mCurrentVideoValues, mOnVideoSavedListener);
logVideoCapture(duration);
}
mCurrentVideoValues = null;
}
private static BucketEntry[] loadBucketEntriesFromImagesAndVideoTable(
ThreadPool.JobContext jc, ContentResolver resolver, int type) {
HashMap<Integer, BucketEntry> buckets = new HashMap<Integer, BucketEntry>(64);
if ((type & MediaObject.MEDIA_TYPE_IMAGE) != 0) {
updateBucketEntriesFromTable(
jc, resolver, Images.Media.EXTERNAL_CONTENT_URI, buckets);
}
if ((type & MediaObject.MEDIA_TYPE_VIDEO) != 0) {
updateBucketEntriesFromTable(
jc, resolver, Video.Media.EXTERNAL_CONTENT_URI, buckets);
}
BucketEntry[] entries = buckets.values().toArray(new BucketEntry[buckets.size()]);
Arrays.sort(entries, new Comparator<BucketEntry>() {
@Override
public int compare(BucketEntry a, BucketEntry b) {
// sorted by dateTaken in descending order
return b.dateTaken - a.dateTaken;
}
});
return entries;
}
public LocalVideo(Path path, MediaDataContext context, int id) {
super(path, nextVersionNumber());
mApplication = context;
ContentResolver resolver = mApplication.getContentResolver();
Uri uri = Video.Media.EXTERNAL_CONTENT_URI;
Cursor cursor = LocalAlbum.getItemCursor(resolver, uri, PROJECTION, id);
if (cursor == null) {
throw new RuntimeException("cannot get cursor for: " + path);
}
try {
if (cursor.moveToNext()) {
loadFromCursor(cursor);
} else {
throw new RuntimeException("cannot find data for: " + path);
}
} finally {
cursor.close();
}
}
protected long getVideoForBucketCleared(long bucketId)
throws FileNotFoundException {
final ContentResolver resolver = getContext().getContentResolver();
Cursor cursor = null;
try {
cursor = resolver.query(Video.Media.EXTERNAL_CONTENT_URI,
VideosBucketThumbnailQuery.PROJECTION, VideoColumns.BUCKET_ID + "=" + bucketId,
null, VideoColumns.DATE_MODIFIED + " DESC");
if (cursor.moveToFirst()) {
return cursor.getLong(VideosBucketThumbnailQuery._ID);
}
} finally {
IoUtils.closeQuietly(cursor);
}
throw new FileNotFoundException("No video found for bucket");
}
protected AssetFileDescriptor openVideoThumbnailCleared(long id, CancellationSignal signal)
throws FileNotFoundException {
final ContentResolver resolver = getContext().getContentResolver();
Cursor cursor = null;
try {
cursor = resolver.query(Video.Thumbnails.EXTERNAL_CONTENT_URI,
VideoThumbnailQuery.PROJECTION, Video.Thumbnails.VIDEO_ID + "=" + id, null,
null);
if (cursor.moveToFirst()) {
final String data = cursor.getString(VideoThumbnailQuery._DATA);
return new AssetFileDescriptor(ParcelFileDescriptor.open(
new File(data), ParcelFileDescriptor.MODE_READ_ONLY), 0,
AssetFileDescriptor.UNKNOWN_LENGTH);
}
} finally {
IoUtils.closeQuietly(cursor);
}
return null;
}
protected AssetFileDescriptor openOrCreateVideoThumbnailCleared(
long id, CancellationSignal signal) throws FileNotFoundException {
final ContentResolver resolver = getContext().getContentResolver();
AssetFileDescriptor afd = openVideoThumbnailCleared(id, signal);
if (afd == null) {
// No thumbnail yet, so generate. This is messy, since we drop the
// Bitmap on the floor, but its the least-complicated way.
final BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inJustDecodeBounds = true;
Video.Thumbnails.getThumbnail(resolver, id, Video.Thumbnails.MINI_KIND, opts);
afd = openVideoThumbnailCleared(id, signal);
}
return afd;
}
protected long getVideoForBucketCleared(long bucketId)
throws FileNotFoundException {
final ContentResolver resolver = getContext().getContentResolver();
Cursor cursor = null;
try {
cursor = resolver.query(Video.Media.EXTERNAL_CONTENT_URI,
VideosBucketThumbnailQuery.PROJECTION, VideoColumns.BUCKET_ID + "=" + bucketId,
null, VideoColumns.DATE_MODIFIED + " DESC");
if (cursor.moveToFirst()) {
return cursor.getLong(VideosBucketThumbnailQuery._ID);
}
} finally {
IoUtils.closeQuietly(cursor);
}
throw new FileNotFoundException("No video found for bucket");
}
protected AssetFileDescriptor openVideoThumbnailCleared(long id, CancellationSignal signal)
throws FileNotFoundException {
final ContentResolver resolver = getContext().getContentResolver();
Cursor cursor = null;
try {
cursor = resolver.query(Video.Thumbnails.EXTERNAL_CONTENT_URI,
VideoThumbnailQuery.PROJECTION, Video.Thumbnails.VIDEO_ID + "=" + id, null,
null);
if (cursor.moveToFirst()) {
final String data = cursor.getString(VideoThumbnailQuery._DATA);
return new AssetFileDescriptor(ParcelFileDescriptor.open(
new File(data), ParcelFileDescriptor.MODE_READ_ONLY), 0,
AssetFileDescriptor.UNKNOWN_LENGTH);
}
} finally {
IoUtils.closeQuietly(cursor);
}
return null;
}
protected AssetFileDescriptor openOrCreateVideoThumbnailCleared(
long id, CancellationSignal signal) throws FileNotFoundException {
final ContentResolver resolver = getContext().getContentResolver();
AssetFileDescriptor afd = openVideoThumbnailCleared(id, signal);
if (afd == null) {
// No thumbnail yet, so generate. This is messy, since we drop the
// Bitmap on the floor, but its the least-complicated way.
final BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inJustDecodeBounds = true;
Video.Thumbnails.getThumbnail(resolver, id, Video.Thumbnails.MINI_KIND, opts);
afd = openVideoThumbnailCleared(id, signal);
}
return afd;
}
protected long getVideoForBucketCleared(long bucketId)
throws FileNotFoundException {
final ContentResolver resolver = getContext().getContentResolver();
Cursor cursor = null;
try {
cursor = resolver.query(Video.Media.EXTERNAL_CONTENT_URI,
VideosBucketThumbnailQuery.PROJECTION, VideoColumns.BUCKET_ID + "=" + bucketId,
null, VideoColumns.DATE_MODIFIED + " DESC");
if (cursor.moveToFirst()) {
return cursor.getLong(VideosBucketThumbnailQuery._ID);
}
} finally {
IoUtils.closeQuietly(cursor);
}
throw new FileNotFoundException("No video found for bucket");
}
protected AssetFileDescriptor openVideoThumbnailCleared(long id, CancellationSignal signal)
throws FileNotFoundException {
final ContentResolver resolver = getContext().getContentResolver();
Cursor cursor = null;
try {
cursor = resolver.query(Video.Thumbnails.EXTERNAL_CONTENT_URI,
VideoThumbnailQuery.PROJECTION, Video.Thumbnails.VIDEO_ID + "=" + id, null,
null);
if (cursor.moveToFirst()) {
final String data = cursor.getString(VideoThumbnailQuery._DATA);
return new AssetFileDescriptor(ParcelFileDescriptor.open(
new File(data), ParcelFileDescriptor.MODE_READ_ONLY), 0,
AssetFileDescriptor.UNKNOWN_LENGTH);
}
} finally {
IoUtils.closeQuietly(cursor);
}
return null;
}
protected AssetFileDescriptor openOrCreateVideoThumbnailCleared(
long id, CancellationSignal signal) throws FileNotFoundException {
final ContentResolver resolver = getContext().getContentResolver();
AssetFileDescriptor afd = openVideoThumbnailCleared(id, signal);
if (afd == null) {
// No thumbnail yet, so generate. This is messy, since we drop the
// Bitmap on the floor, but its the least-complicated way.
final BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inJustDecodeBounds = true;
Video.Thumbnails.getThumbnail(resolver, id, Video.Thumbnails.MINI_KIND, opts);
afd = openVideoThumbnailCleared(id, signal);
}
return afd;
}
public synchronized void cancelThreadDecoding(Thread t, ContentResolver cr) {
ThreadStatus status = getOrCreateThreadStatus(t);
status.mState = State.CANCEL;
if (status.mOptions != null) {
status.mOptions.requestCancelDecode();
}
// Wake up threads in waiting list
notifyAll();
// Since our cancel request can arrive MediaProvider earlier than getThumbnail request,
// we use mThumbRequesting flag to make sure our request does cancel the request.
try {
synchronized (status) {
while (status.mThumbRequesting) {
Images.Thumbnails.cancelThumbnailRequest(cr, -1, t.getId());
Video.Thumbnails.cancelThumbnailRequest(cr, -1, t.getId());
status.wait(200);
}
}
} catch (InterruptedException ex) {
// ignore it.
}
}
public Bitmap getThumbnail(ContentResolver cr, long origId, int kind, BitmapFactory.Options options, boolean isVideo) {
Thread t = Thread.currentThread();
ThreadStatus status = getOrCreateThreadStatus(t);
if (!canThreadDecoding(t)) {
Log.d(TAG, "Thread " + t + " is not allowed to decode.");
return null;
}
try {
synchronized (status) {
status.mThumbRequesting = true;
}
if (isVideo) {
return Video.Thumbnails.getThumbnail(cr, origId, t.getId(), kind, null);
} else {
return Images.Thumbnails.getThumbnail(cr, origId, t.getId(), kind, null);
}
} finally {
synchronized (status) {
status.mThumbRequesting = false;
status.notifyAll();
}
}
}
@Nullable
/**
* Creates external content:// scheme uri to save the videos at.
**/
public static Uri createVideoUri(Context ctx) throws IOException {
if (ctx == null) {
throw new NullPointerException("Context cannot be null");
}
Uri imageUri = null;
ContentValues values = new ContentValues();
values.put(MediaStore.MediaColumns.TITLE, "");
values.put(MediaStore.Images.ImageColumns.DESCRIPTION, "");
imageUri = ctx.getContentResolver().insert(Video.Media.EXTERNAL_CONTENT_URI, values);
return imageUri;
}
@Nullable
/**
* @deprecated Use {@link MediaUtils#createVideoUri(Context)}
* Creates external content:// scheme uri to save the videos at.
*/
public static Uri createVideoUri(Context ctx) throws IOException {
if (ctx == null) {
throw new NullPointerException("Context cannot be null");
}
Uri imageUri;
ContentValues values = new ContentValues();
values.put(MediaColumns.TITLE, "");
values.put(ImageColumns.DESCRIPTION, "");
imageUri = ctx.getContentResolver().insert(Video.Media.EXTERNAL_CONTENT_URI, values);
return imageUri;
}
@Override
public boolean handleMessage(Message message) {
// done on async thread
final View view = (View) message.obj;
final ImageView thumbImageView = (ImageView) view.findViewById(R.id.thumbnail);
Bitmap bitmap = Images.Thumbnails.getThumbnail(context.getContentResolver(),
message.what, Images.Thumbnails.MICRO_KIND, null);
if (bitmap == null) {
bitmap = Video.Thumbnails.getThumbnail(context.getContentResolver(),
message.what, Video.Thumbnails.MICRO_KIND, null);
}
final Bitmap fBitmap = bitmap;
// back on UI thread to set the bitmap to the view
new Handler(context.getMainLooper()).post(new Runnable() {
@Override
public void run() {
thumbImageView.setImageBitmap(fBitmap);
}
});
return true;
}
public static String createFinalPath(Context context)
{
long dateTaken = System.currentTimeMillis();
String title = CONSTANTS.FILE_START_NAME + dateTaken;
String filename = title + CONSTANTS.VIDEO_EXTENSION;
String filePath = genrateFilePath(context,String.valueOf(dateTaken), true, null);
ContentValues values = new ContentValues(7);
values.put(Video.Media.TITLE, title);
values.put(Video.Media.DISPLAY_NAME, filename);
values.put(Video.Media.DATE_TAKEN, dateTaken);
values.put(Video.Media.MIME_TYPE, "video/3gpp");
values.put(Video.Media.DATA, filePath);
videoContentValues = values;
return filePath;
}
public synchronized void cancelThreadDecoding(Thread t, ContentResolver cr) {
ThreadStatus status = getOrCreateThreadStatus(t);
status.mState = State.CANCEL;
if (status.mOptions != null) {
status.mOptions.requestCancelDecode();
}
// Wake up threads in waiting list
notifyAll();
// Since our cancel request can arrive MediaProvider earlier than getThumbnail request,
// we use mThumbRequesting flag to make sure our request does cancel the request.
try {
synchronized (status) {
while (status.mThumbRequesting) {
Images.Thumbnails.cancelThumbnailRequest(cr, -1, t.getId());
Video.Thumbnails.cancelThumbnailRequest(cr, -1, t.getId());
status.wait(200);
}
}
} catch (InterruptedException ex) {
// ignore it.
}
}
public synchronized void cancelThreadDecoding(Thread t, ContentResolver cr) {
ThreadStatus status = getOrCreateThreadStatus(t);
status.mState = State.CANCEL;
if (status.mOptions != null) {
status.mOptions.requestCancelDecode();
}
// Wake up threads in waiting list
notifyAll();
// Since our cancel request can arrive MediaProvider earlier than getThumbnail request,
// we use mThumbRequesting flag to make sure our request does cancel the request.
try {
synchronized (status) {
while (status.mThumbRequesting) {
Images.Thumbnails.cancelThumbnailRequest(cr, -1, t.getId());
Video.Thumbnails.cancelThumbnailRequest(cr, -1, t.getId());
status.wait(200);
}
}
} catch (InterruptedException ex) {
// ignore it.
}
}
public static String createFinalPath(Context context)
{
long dateTaken = System.currentTimeMillis();
String title = CONSTANTS.FILE_START_NAME + dateTaken;
String filename = title + CONSTANTS.VIDEO_EXTENSION;
String filePath = genrateFilePath(context,String.valueOf(dateTaken), true, null);
ContentValues values = new ContentValues(7);
values.put(Video.Media.TITLE, title);
values.put(Video.Media.DISPLAY_NAME, filename);
values.put(Video.Media.DATE_TAKEN, dateTaken);
values.put(Video.Media.MIME_TYPE, "video/3gpp");
values.put(Video.Media.DATA, filePath);
videoContentValues = values;
return filePath;
}
@Override
public void onCreate() {
super.onCreate();
instance = this;
LOG.debug("Service created…");
running = true;
getContentResolver().registerContentObserver(Images.Media.EXTERNAL_CONTENT_URI, true, imageTableObserver);
getContentResolver().registerContentObserver(Video.Media.EXTERNAL_CONTENT_URI, true, imageTableObserver);
if (thread == null || !thread.isAlive()) {
thread = new Thread(new UploadRunnable());
thread.start();
}
IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
registerReceiver(batteryReceiver, filter);
checkNewFiles();
Notifications.init();
}
@WorkerThread
private @NonNull List<Media> getMediaInBucket(@NonNull Context context, @NonNull String bucketId, @NonNull Uri contentUri, boolean isImage) {
List<Media> media = new LinkedList<>();
String selection = Images.Media.BUCKET_ID + " = ? AND " + Images.Media.DATA + " NOT NULL";
String[] selectionArgs = new String[] { bucketId };
String sortBy = Images.Media.DATE_MODIFIED + " DESC";
String[] projection;
if (isImage) {
projection = new String[]{Images.Media.DATA, Images.Media.MIME_TYPE, Images.Media.DATE_MODIFIED, Images.Media.ORIENTATION, Images.Media.WIDTH, Images.Media.HEIGHT, Images.Media.SIZE};
} else {
projection = new String[]{Images.Media.DATA, Images.Media.MIME_TYPE, Images.Media.DATE_MODIFIED, Images.Media.WIDTH, Images.Media.HEIGHT, Images.Media.SIZE, Video.Media.DURATION};
}
if (Media.ALL_MEDIA_BUCKET_ID.equals(bucketId)) {
selection = Images.Media.DATA + " NOT NULL";
selectionArgs = null;
}
try (Cursor cursor = context.getContentResolver().query(contentUri, projection, selection, selectionArgs, sortBy)) {
while (cursor != null && cursor.moveToNext()) {
String path = cursor.getString(cursor.getColumnIndexOrThrow(projection[0]));
Uri uri = Uri.fromFile(new File(path));
String mimetype = cursor.getString(cursor.getColumnIndexOrThrow(Images.Media.MIME_TYPE));
long date = cursor.getLong(cursor.getColumnIndexOrThrow(Images.Media.DATE_MODIFIED));
int orientation = isImage ? cursor.getInt(cursor.getColumnIndexOrThrow(Images.Media.ORIENTATION)) : 0;
int width = cursor.getInt(cursor.getColumnIndexOrThrow(getWidthColumn(orientation)));
int height = cursor.getInt(cursor.getColumnIndexOrThrow(getHeightColumn(orientation)));
long size = cursor.getLong(cursor.getColumnIndexOrThrow(Images.Media.SIZE));
long duration = !isImage ? cursor.getInt(cursor.getColumnIndexOrThrow(Video.Media.DURATION)) : 0;
media.add(new Media(uri, mimetype, date, width, height, size, duration, Optional.of(bucketId), Optional.absent(), Optional.absent()));
}
}
return media;
}
private void generateVideoFilename(int outputFileFormat)
{
long dateTaken = System.currentTimeMillis();
String title = createName(dateTaken);
// Used when emailing.
String filename = title + convertOutputFormatToFileExt(outputFileFormat);
String mime = convertOutputFormatToMimeType(outputFileFormat);
String path = Storage.DIRECTORY + '/' + filename;
String tmpPath = path + ".tmp";
mCurrentVideoValues = new ContentValues(9);
mCurrentVideoValues.put(Video.Media.TITLE, title);
mCurrentVideoValues.put(Video.Media.DISPLAY_NAME, filename);
mCurrentVideoValues.put(Video.Media.DATE_TAKEN, dateTaken);
mCurrentVideoValues.put(MediaColumns.DATE_MODIFIED, dateTaken / 1000);
mCurrentVideoValues.put(Video.Media.MIME_TYPE, mime);
mCurrentVideoValues.put(Video.Media.DATA, path);
mCurrentVideoValues.put(Video.Media.WIDTH, mProfile.videoFrameWidth);
mCurrentVideoValues.put(Video.Media.HEIGHT, mProfile.videoFrameHeight);
mCurrentVideoValues.put(Video.Media.RESOLUTION,
Integer.toString(mProfile.videoFrameWidth) + "x" +
Integer.toString(mProfile.videoFrameHeight));
Location loc = mLocationManager.getCurrentLocation();
if (loc != null)
{
mCurrentVideoValues.put(Video.Media.LATITUDE, loc.getLatitude());
mCurrentVideoValues.put(Video.Media.LONGITUDE, loc.getLongitude());
}
mVideoFilename = tmpPath;
Log.v(TAG, "New video filename: " + mVideoFilename);
}
private void logVideoCapture(long duration)
{
String flashSetting = mActivity.getSettingsManager()
.getString(mAppController.getCameraScope(),
Keys.KEY_VIDEOCAMERA_FLASH_MODE);
boolean gridLinesOn = Keys.areGridLinesOn(mActivity.getSettingsManager());
int width = (Integer) mCurrentVideoValues.get(Video.Media.WIDTH);
int height = (Integer) mCurrentVideoValues.get(Video.Media.HEIGHT);
long size = new File(mCurrentVideoFilename).length();
String name = new File(mCurrentVideoValues.getAsString(Video.Media.DATA)).getName();
UsageStatistics.instance().videoCaptureDoneEvent(name, duration, isCameraFrontFacing(),
currentZoomValue(), width, height, size, flashSetting, gridLinesOn);
}
@Override
protected Uri doInBackground(Void... v)
{
Uri uri = null;
try
{
Uri videoTable = Uri.parse(VIDEO_BASE_URI);
uri = resolver.insert(videoTable, values);
// Rename the video file to the final name. This avoids other
// apps reading incomplete data. We need to do it after we are
// certain that the previous insert to MediaProvider is completed.
String finalName = values.getAsString(Video.Media.DATA);
File finalFile = new File(finalName);
if (new File(path).renameTo(finalFile))
{
path = finalName;
}
resolver.update(uri, values, null, null);
} catch (Exception e)
{
// We failed to insert into the database. This can happen if
// the SD card is unmounted.
Log.e(TAG, "failed to add video to media store", e);
uri = null;
} finally
{
Log.v(TAG, "Current video URI: " + uri);
}
return uri;
}
public LocalAlbum(Path path, MediaDataContext application, int bucketId,
boolean isImage, String name) {
super(path, nextVersionNumber());
mApplication = application;
mResolver = application.getContentResolver();
mBucketId = bucketId;
mName = name;
mIsImage = isImage;
if (isImage) {
mWhereClause = ImageColumns.BUCKET_ID + " = ?";
mOrderClause = ImageColumns.DATE_TAKEN + " DESC, "
+ ImageColumns._ID + " DESC";
mBaseUri = Images.Media.EXTERNAL_CONTENT_URI;
mProjection = LocalImage.PROJECTION;
mItemPath = LocalImage.ITEM_PATH;
} else {
mWhereClause = VideoColumns.BUCKET_ID + " = ?";
mOrderClause = VideoColumns.DATE_TAKEN + " DESC, "
+ VideoColumns._ID + " DESC";
mBaseUri = Video.Media.EXTERNAL_CONTENT_URI;
mProjection = LocalVideo.PROJECTION;
mItemPath = LocalVideo.ITEM_PATH;
}
mNotifier = new ChangeNotifier(this, mBaseUri, application);
}
@Override
public Uri getContentUri() {
if (mIsImage) {
return Images.Media.EXTERNAL_CONTENT_URI.buildUpon()
.appendQueryParameter(LocalSource.KEY_BUCKET_ID,
String.valueOf(mBucketId)).build();
} else {
return Video.Media.EXTERNAL_CONTENT_URI.buildUpon()
.appendQueryParameter(LocalSource.KEY_BUCKET_ID,
String.valueOf(mBucketId)).build();
}
}
@Override
public void delete() {
GalleryUtils.assertNotInRenderThread();
Uri baseUri = Video.Media.EXTERNAL_CONTENT_URI;
mApplication.getContentResolver().delete(baseUri, "_id=?",
new String[]{String.valueOf(id)});
}