mirror of
https://github.com/nextcloud/android.git
synced 2024-11-23 13:45:35 +03:00
add video fetching
This commit is contained in:
parent
81cc7eb5d7
commit
105ce09649
3 changed files with 148 additions and 9 deletions
|
@ -47,12 +47,15 @@ public class MediaProvider {
|
|||
private static final String TAG = MediaProvider.class.getSimpleName();
|
||||
|
||||
// fixed query parameters
|
||||
private static final Uri MEDIA_URI = android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
|
||||
private static final Uri IMAGES_MEDIA_URI = android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
|
||||
private static final String[] FILE_PROJECTION = new String[]{MediaStore.MediaColumns.DATA};
|
||||
private static final String FILE_SELECTION = MediaStore.Images.Media.BUCKET_ID + "=";
|
||||
private static final String[] FOLDER_PROJECTION = { "Distinct " + MediaStore.Images.Media.BUCKET_ID,
|
||||
private static final String IMAGES_FILE_SELECTION = MediaStore.Images.Media.BUCKET_ID + "=";
|
||||
private static final String[] IMAGES_FOLDER_PROJECTION = { "Distinct " + MediaStore.Images.Media.BUCKET_ID,
|
||||
MediaStore.Images.Media.BUCKET_DISPLAY_NAME };
|
||||
private static final String FOLDER_SORT_ORDER = MediaStore.Images.Media.BUCKET_DISPLAY_NAME + " ASC";
|
||||
private static final String IMAGES_FOLDER_SORT_ORDER = MediaStore.Images.Media.BUCKET_DISPLAY_NAME + " ASC";
|
||||
|
||||
private static final String[] VIDEOS_FOLDER_PROJECTION = { "Distinct " + MediaStore.Video.Media.BUCKET_ID,
|
||||
MediaStore.Video.Media.BUCKET_DISPLAY_NAME };
|
||||
|
||||
/**
|
||||
* Getting All Images Paths.
|
||||
|
@ -61,7 +64,7 @@ public class MediaProvider {
|
|||
* @param itemLimit the number of media items (usually images) to be returned per media folder.
|
||||
* @return list with media folders
|
||||
*/
|
||||
public static List<MediaFolder> getMediaFolders(ContentResolver contentResolver, int itemLimit,
|
||||
public static List<MediaFolder> getImageFolders(ContentResolver contentResolver, int itemLimit,
|
||||
final Activity activity) {
|
||||
// check permissions
|
||||
if (!PermissionUtil.checkSelfPermission(activity.getApplicationContext(),
|
||||
|
@ -92,7 +95,7 @@ public class MediaProvider {
|
|||
Cursor cursorFolders = null;
|
||||
if (PermissionUtil.checkSelfPermission(activity.getApplicationContext(),
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
|
||||
cursorFolders = contentResolver.query(MEDIA_URI, FOLDER_PROJECTION, null, null, FOLDER_SORT_ORDER);
|
||||
cursorFolders = contentResolver.query(IMAGES_MEDIA_URI, IMAGES_FOLDER_PROJECTION, null, null, IMAGES_FOLDER_SORT_ORDER);
|
||||
}
|
||||
List<MediaFolder> mediaFolders = new ArrayList<>();
|
||||
String dataPath = MainApp.getStoragePath() + File.separator + MainApp.getDataFolder();
|
||||
|
@ -113,7 +116,7 @@ public class MediaProvider {
|
|||
mediaFolder.filePaths = new ArrayList<>();
|
||||
|
||||
// query images
|
||||
cursorImages = contentResolver.query(MEDIA_URI, FILE_PROJECTION, FILE_SELECTION + folderId, null,
|
||||
cursorImages = contentResolver.query(IMAGES_MEDIA_URI, FILE_PROJECTION, IMAGES_FILE_SELECTION + folderId, null,
|
||||
fileSortOrder);
|
||||
Log.d(TAG, "Reading images for " + mediaFolder.folderName);
|
||||
|
||||
|
@ -138,9 +141,75 @@ public class MediaProvider {
|
|||
|
||||
// count images
|
||||
Cursor count = contentResolver.query(
|
||||
MEDIA_URI,
|
||||
IMAGES_MEDIA_URI,
|
||||
FILE_PROJECTION,
|
||||
FILE_SELECTION + folderId,
|
||||
IMAGES_FILE_SELECTION + folderId,
|
||||
null,
|
||||
null);
|
||||
|
||||
if (count != null) {
|
||||
mediaFolder.numberOfFiles = count.getCount();
|
||||
count.close();
|
||||
}
|
||||
|
||||
mediaFolders.add(mediaFolder);
|
||||
}
|
||||
}
|
||||
}
|
||||
cursorFolders.close();
|
||||
}
|
||||
|
||||
return mediaFolders;
|
||||
}
|
||||
|
||||
public static List<MediaFolder> getMediaFolders(ContentResolver contentResolver, int itemLimit) {
|
||||
Cursor cursorFolders = contentResolver.query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
|
||||
VIDEOS_FOLDER_PROJECTION, null, null, null);
|
||||
List<MediaFolder> mediaFolders = new ArrayList<>();
|
||||
String dataPath = MainApp.getStoragePath() + File.separator + MainApp.getDataFolder();
|
||||
|
||||
if (cursorFolders != null) {
|
||||
String folderName;
|
||||
String fileSortOrder = MediaStore.Video.Media.DATE_TAKEN + " DESC LIMIT " + itemLimit;
|
||||
Cursor cursorImages;
|
||||
|
||||
while (cursorFolders.moveToNext()) {
|
||||
String folderId = cursorFolders.getString(cursorFolders.getColumnIndex(MediaStore.Video.Media
|
||||
.BUCKET_ID));
|
||||
|
||||
MediaFolder mediaFolder = new MediaFolder();
|
||||
folderName = cursorFolders.getString(cursorFolders.getColumnIndex(
|
||||
MediaStore.Video.Media.BUCKET_DISPLAY_NAME));
|
||||
mediaFolder.folderName = folderName;
|
||||
mediaFolder.filePaths = new ArrayList<>();
|
||||
|
||||
// query images
|
||||
cursorImages = contentResolver.query(
|
||||
MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
|
||||
FILE_PROJECTION,
|
||||
MediaStore.Video.Media.BUCKET_ID + "=" + folderId,
|
||||
null,
|
||||
fileSortOrder);
|
||||
Log.d(TAG, "Reading videos for " + mediaFolder.folderName);
|
||||
|
||||
if (cursorImages != null) {
|
||||
String filePath;
|
||||
while (cursorImages.moveToNext()) {
|
||||
filePath = cursorImages.getString(cursorImages.getColumnIndexOrThrow(
|
||||
MediaStore.MediaColumns.DATA));
|
||||
mediaFolder.filePaths.add(filePath);
|
||||
mediaFolder.absolutePath = filePath.substring(0, filePath.lastIndexOf("/"));
|
||||
}
|
||||
cursorImages.close();
|
||||
|
||||
// only do further work if folder is not within the Nextcloud app itself
|
||||
if (!mediaFolder.absolutePath.startsWith(dataPath)) {
|
||||
|
||||
// count images
|
||||
Cursor count = contentResolver.query(
|
||||
MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
|
||||
FILE_PROJECTION,
|
||||
MediaStore.Video.Media.BUCKET_ID + "=" + folderId,
|
||||
null,
|
||||
null);
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ import android.graphics.Canvas;
|
|||
import android.graphics.Paint;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.media.MediaMetadataRetriever;
|
||||
import android.media.ThumbnailUtils;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
|
@ -440,6 +441,8 @@ public class ThumbnailsCacheManager {
|
|||
|
||||
if (MimeTypeUtil.isImage(mFile)) {
|
||||
thumbnail = doFileInBackground(mFile);
|
||||
} else if (MimeTypeUtil.isVideo(mFile)) {
|
||||
thumbnail = doVideoInBackground(mFile);
|
||||
}
|
||||
}
|
||||
} // the app should never break due to a problem with thumbnails
|
||||
|
@ -464,6 +467,7 @@ public class ThumbnailsCacheManager {
|
|||
|
||||
if (bitmap != null) {
|
||||
if (tagId.equals(String.valueOf(imageView.getTag()))) {
|
||||
Log_OC.e(TAG, "SET RENDERED VIDEO THUMBNAIL");
|
||||
imageView.setImageBitmap(bitmap);
|
||||
}
|
||||
} else {
|
||||
|
@ -473,6 +477,7 @@ public class ThumbnailsCacheManager {
|
|||
} else {
|
||||
if (MimeTypeUtil.isVideo(mFile)) {
|
||||
imageView.setImageBitmap(ThumbnailsCacheManager.mDefaultVideo);
|
||||
Log_OC.e(TAG, "SET VIDEO THUMBNAIL");
|
||||
} else {
|
||||
imageView.setImageDrawable(MimeTypeUtil.getFileTypeIcon(null, mFile.getName(), null));
|
||||
}
|
||||
|
@ -507,6 +512,53 @@ public class ThumbnailsCacheManager {
|
|||
}
|
||||
return thumbnail;
|
||||
}
|
||||
|
||||
private Bitmap doVideoInBackground(File file) {
|
||||
Bitmap bitmap = null;
|
||||
final String imageKey;
|
||||
|
||||
if (mImageKey != null) {
|
||||
imageKey = mImageKey;
|
||||
} else {
|
||||
imageKey = String.valueOf(file.hashCode());
|
||||
}
|
||||
|
||||
// Check disk cache in background thread
|
||||
Bitmap thumbnail = getBitmapFromDiskCache(imageKey);
|
||||
|
||||
// Not found in disk cache
|
||||
if (thumbnail == null) {
|
||||
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
|
||||
try {
|
||||
retriever.setDataSource(file.getAbsolutePath());
|
||||
bitmap = retriever.getFrameAtTime(-1);
|
||||
} catch (Exception ex) {
|
||||
// can't create a bitmap
|
||||
} finally {
|
||||
try {
|
||||
retriever.release();
|
||||
} catch (RuntimeException ex) {
|
||||
// Ignore failure at this point.
|
||||
}
|
||||
}
|
||||
|
||||
if (bitmap == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Scale down bitmap if too large.
|
||||
int px = getThumbnailDimension();
|
||||
int width = bitmap.getWidth();
|
||||
int height = bitmap.getHeight();
|
||||
int max = Math.max(width, height);
|
||||
if (max > px) {
|
||||
bitmap = BitmapUtils.scaleBitmap(bitmap, px, width, height, max);
|
||||
bitmap = addThumbnailToCache(imageKey, bitmap, file.getPath(), px);
|
||||
}
|
||||
}
|
||||
|
||||
return bitmap;
|
||||
}
|
||||
}
|
||||
|
||||
public static class AvatarGenerationTask extends AsyncTask<String, Void, Bitmap> {
|
||||
|
|
|
@ -106,6 +106,24 @@ public class BitmapUtils {
|
|||
return inSampleSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* scales a given bitmap depending on the given size parameters.
|
||||
*
|
||||
* @param bitmap the bitmap to be scaled
|
||||
* @param px the target pixel size
|
||||
* @param width the width
|
||||
* @param height the height
|
||||
* @param max the max(height, width)
|
||||
* @return the scaled bitmap
|
||||
*/
|
||||
public static Bitmap scaleBitmap(Bitmap bitmap, float px, int width, int height, int max) {
|
||||
float scale = px / max;
|
||||
int w = Math.round(scale * width);
|
||||
int h = Math.round(scale * height);
|
||||
bitmap = Bitmap.createScaledBitmap(bitmap, w, h, true);
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotate bitmap according to EXIF orientation.
|
||||
* Cf. http://www.daveperrett.com/articles/2012/07/28/exif-orientation-handling-is-a-ghetto/
|
||||
|
|
Loading…
Reference in a new issue