/*
* Nextcloud Android client application
*
* @author Andy Scherzinger
* Copyright (C) 2016 Andy Scherzinger
* Copyright (C) 2016 Nextcloud
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
* License as published by the Free Software Foundation; either
* version 3 of the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
*
* You should have received a copy of the GNU Affero General Public
* License along with this program. If not, see .
*/
package com.owncloud.android.datamodel;
import android.Manifest;
import android.app.Activity;
import android.content.ContentResolver;
import android.database.Cursor;
import android.net.Uri;
import android.provider.MediaStore;
import android.support.design.widget.Snackbar;
import android.util.Log;
import android.view.View;
import com.owncloud.android.MainApp;
import com.owncloud.android.R;
import com.owncloud.android.utils.PermissionUtil;
import com.owncloud.android.utils.ThemeUtils;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
/**
* Media queries to gain access to media lists for the device.
*/
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 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,
MediaStore.Images.Media.BUCKET_DISPLAY_NAME };
private static final String FOLDER_SORT_ORDER = MediaStore.Images.Media.BUCKET_DISPLAY_NAME + " ASC";
/**
* Getting All Images Paths.
*
* @param contentResolver the content resolver
* @param itemLimit the number of media items (usually images) to be returned per media folder.
* @return list with media folders
*/
public static List getMediaFolders(ContentResolver contentResolver, int itemLimit,
final Activity activity) {
// check permissions
if (!PermissionUtil.checkSelfPermission(activity.getApplicationContext(),
Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
// Check if we should show an explanation
if (PermissionUtil.shouldShowRequestPermissionRationale(activity,
Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
// Show explanation to the user and then request permission
Snackbar snackbar = Snackbar.make(activity.findViewById(R.id.ListLayout),
R.string.permission_storage_access, Snackbar.LENGTH_INDEFINITE)
.setAction(R.string.common_ok, new View.OnClickListener() {
@Override
public void onClick(View v) {
PermissionUtil.requestWriteExternalStoreagePermission(activity);
}
});
ThemeUtils.colorSnackbar(activity.getApplicationContext(), snackbar);
snackbar.show();
} else {
// No explanation needed, request the permission.
PermissionUtil.requestWriteExternalStoreagePermission(activity);
}
}
// query media/image folders
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);
}
List mediaFolders = new ArrayList<>();
String dataPath = MainApp.getStoragePath() + File.separator + MainApp.getDataFolder();
if (cursorFolders != null) {
String folderName;
String fileSortOrder = MediaStore.Images.Media.DATE_TAKEN + " DESC LIMIT " + itemLimit;
Cursor cursorImages;
while (cursorFolders.moveToNext()) {
String folderId = cursorFolders.getString(cursorFolders.getColumnIndex(MediaStore.Images.Media
.BUCKET_ID));
MediaFolder mediaFolder = new MediaFolder();
folderName = cursorFolders.getString(cursorFolders.getColumnIndex(
MediaStore.Images.Media.BUCKET_DISPLAY_NAME));
mediaFolder.folderName = folderName;
mediaFolder.filePaths = new ArrayList<>();
// query images
cursorImages = contentResolver.query(MEDIA_URI, FILE_PROJECTION, FILE_SELECTION + folderId, null,
fileSortOrder);
Log.d(TAG, "Reading images for " + mediaFolder.folderName);
if (cursorImages != null) {
String filePath;
int failedImages = 0;
while (cursorImages.moveToNext()) {
filePath = cursorImages.getString(cursorImages.getColumnIndexOrThrow(
MediaStore.MediaColumns.DATA));
if (filePath != null) {
mediaFolder.filePaths.add(filePath);
mediaFolder.absolutePath = filePath.substring(0, filePath.lastIndexOf("/"));
} else {
failedImages++;
}
}
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(
MEDIA_URI,
FILE_PROJECTION,
FILE_SELECTION + folderId,
null,
null);
if (count != null) {
mediaFolder.numberOfFiles = count.getCount() - failedImages;
count.close();
}
mediaFolders.add(mediaFolder);
}
}
}
cursorFolders.close();
}
return mediaFolders;
}
}