blob: 16c2c5ccca685f1a6d6833a1ac7a424b38b7effb [file] [log] [blame]
package org.wordpress.android.ui.media;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Fragment;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v4.content.FileProvider;
import android.widget.ImageView;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.NetworkImageView;
import org.wordpress.android.R;
import org.wordpress.android.WordPress;
import org.wordpress.android.WordPressDB;
import org.wordpress.android.ui.RequestCodes;
import org.wordpress.android.util.AppLog;
import org.wordpress.android.util.AppLog.T;
import org.wordpress.android.util.DeviceUtils;
import org.wordpress.android.util.MediaUtils;
import org.wordpress.android.util.PhotonUtils;
import org.wordpress.android.util.helpers.Version;
import org.wordpress.passcodelock.AppLockManager;
import java.io.File;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.net.URL;
import static org.wordpress.mediapicker.MediaUtils.fadeInImage;
public class WordPressMediaUtils {
public interface LaunchCameraCallback {
void onMediaCapturePathReady(String mediaCapturePath);
}
private static void showSDCardRequiredDialog(Context context) {
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(context);
dialogBuilder.setTitle(context.getResources().getText(R.string.sdcard_title));
dialogBuilder.setMessage(context.getResources().getText(R.string.sdcard_message));
dialogBuilder.setPositiveButton(context.getString(R.string.ok), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
dialog.dismiss();
}
});
dialogBuilder.setCancelable(true);
dialogBuilder.create().show();
}
public static void launchVideoLibrary(Activity activity) {
AppLockManager.getInstance().setExtendedTimeout();
activity.startActivityForResult(prepareVideoLibraryIntent(activity),
RequestCodes.VIDEO_LIBRARY);
}
public static void launchVideoLibrary(Fragment fragment) {
if (!fragment.isAdded()) {
return;
}
AppLockManager.getInstance().setExtendedTimeout();
fragment.startActivityForResult(prepareVideoLibraryIntent(fragment.getActivity()),
RequestCodes.VIDEO_LIBRARY);
}
public static Intent prepareVideoLibraryIntent(Context context) {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("video/*");
return Intent.createChooser(intent, context.getString(R.string.pick_video));
}
public static void launchVideoCamera(Activity activity) {
AppLockManager.getInstance().setExtendedTimeout();
activity.startActivityForResult(prepareVideoCameraIntent(), RequestCodes.TAKE_VIDEO);
}
public static void launchVideoCamera(Fragment fragment) {
if (!fragment.isAdded()) {
return;
}
AppLockManager.getInstance().setExtendedTimeout();
fragment.startActivityForResult(prepareVideoCameraIntent(), RequestCodes.TAKE_VIDEO);
}
private static Intent prepareVideoCameraIntent() {
return new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
}
public static void launchPictureLibrary(Activity activity) {
AppLockManager.getInstance().setExtendedTimeout();
activity.startActivityForResult(preparePictureLibraryIntent(activity.getString(R.string.pick_photo)),
RequestCodes.PICTURE_LIBRARY);
}
public static void launchPictureLibrary(Fragment fragment) {
if (!fragment.isAdded()) {
return;
}
AppLockManager.getInstance().setExtendedTimeout();
fragment.startActivityForResult(preparePictureLibraryIntent(fragment.getActivity()
.getString(R.string.pick_photo)), RequestCodes.PICTURE_LIBRARY);
}
private static Intent preparePictureLibraryIntent(String title) {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
return Intent.createChooser(intent, title);
}
private static Intent prepareGalleryIntent(String title) {
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
return Intent.createChooser(intent, title);
}
public static void launchCamera(Activity activity, String applicationId, LaunchCameraCallback callback) {
Intent intent = preparelaunchCamera(activity, applicationId, callback);
if (intent != null) {
AppLockManager.getInstance().setExtendedTimeout();
activity.startActivityForResult(intent, RequestCodes.TAKE_PHOTO);
}
}
public static void launchCamera(Fragment fragment, String applicationId, LaunchCameraCallback callback) {
if (!fragment.isAdded()) {
return;
}
Intent intent = preparelaunchCamera(fragment.getActivity(), applicationId, callback);
if (intent != null) {
AppLockManager.getInstance().setExtendedTimeout();
fragment.startActivityForResult(intent, RequestCodes.TAKE_PHOTO);
}
}
private static Intent preparelaunchCamera(Context context, String applicationId, LaunchCameraCallback callback) {
String state = android.os.Environment.getExternalStorageState();
if (!state.equals(android.os.Environment.MEDIA_MOUNTED)) {
showSDCardRequiredDialog(context);
return null;
} else {
return getLaunchCameraIntent(context, applicationId, callback);
}
}
private static Intent getLaunchCameraIntent(Context context, String applicationId, LaunchCameraCallback callback) {
File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
String mediaCapturePath = path + File.separator + "Camera" + File.separator + "wp-" + System
.currentTimeMillis() + ".jpg";
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, FileProvider.getUriForFile(context,
applicationId + ".provider", new File(mediaCapturePath)));
if (callback != null) {
callback.onMediaCapturePathReady(mediaCapturePath);
}
// make sure the directory we plan to store the recording in exists
File directory = new File(mediaCapturePath).getParentFile();
if (!directory.exists() && !directory.mkdirs()) {
try {
throw new IOException("Path to file could not be created.");
} catch (IOException e) {
AppLog.e(T.POSTS, e);
}
}
return intent;
}
public static void launchPictureLibraryOrCapture(Fragment fragment, String applicationId, LaunchCameraCallback
callback) {
if (!fragment.isAdded()) {
return;
}
AppLockManager.getInstance().setExtendedTimeout();
fragment.startActivityForResult(makePickOrCaptureIntent(fragment.getActivity(), applicationId, callback),
RequestCodes.PICTURE_LIBRARY_OR_CAPTURE);
}
private static Intent makePickOrCaptureIntent(Context context, String applicationId, LaunchCameraCallback callback) {
Intent pickPhotoIntent = prepareGalleryIntent(context.getString(R.string.capture_or_pick_photo));
if (DeviceUtils.getInstance().hasCamera(context)) {
Intent cameraIntent = getLaunchCameraIntent(context, applicationId, callback);
pickPhotoIntent.putExtra(
Intent.EXTRA_INITIAL_INTENTS,
new Intent[]{ cameraIntent });
}
return pickPhotoIntent;
}
public static int getPlaceholder(String url) {
if (MediaUtils.isValidImage(url)) {
return R.drawable.media_image_placeholder;
} else if (MediaUtils.isDocument(url)) {
return R.drawable.media_document;
} else if (MediaUtils.isPowerpoint(url)) {
return R.drawable.media_powerpoint;
} else if (MediaUtils.isSpreadsheet(url)) {
return R.drawable.media_spreadsheet;
} else if (MediaUtils.isVideo(url)) {
return org.wordpress.android.editor.R.drawable.media_movieclip;
} else if (MediaUtils.isAudio(url)) {
return R.drawable.media_audio;
} else {
return 0;
}
}
/**
* This is a workaround for WP3.4.2 that deletes the media from the server when editing media properties
* within the app. See: https://github.com/wordpress-mobile/WordPress-Android/issues/204
*/
public static boolean isWordPressVersionWithMediaEditingCapabilities() {
if (WordPress.currentBlog == null) {
return false;
}
if (WordPress.currentBlog.getWpVersion() == null) {
return true;
}
if (WordPress.currentBlog.isDotcomFlag()) {
return true;
}
Version minVersion;
Version currentVersion;
try {
minVersion = new Version("3.5.2");
currentVersion = new Version(WordPress.currentBlog.getWpVersion());
if (currentVersion.compareTo(minVersion) == -1) {
return false;
}
} catch (IllegalArgumentException e) {
AppLog.e(T.POSTS, e);
}
return true;
}
public static boolean canDeleteMedia(String blogId, String mediaID) {
Cursor cursor = WordPress.wpDB.getMediaFile(blogId, mediaID);
if (!cursor.moveToFirst()) {
cursor.close();
return false;
}
String state = cursor.getString(cursor.getColumnIndex("uploadState"));
cursor.close();
return state == null || !state.equals("uploading");
}
public static class BackgroundDownloadWebImage extends AsyncTask<Uri, String, Bitmap> {
WeakReference<ImageView> mReference;
public BackgroundDownloadWebImage(ImageView resultStore) {
mReference = new WeakReference<>(resultStore);
}
@Override
protected Bitmap doInBackground(Uri... params) {
try {
String uri = params[0].toString();
Bitmap bitmap = WordPress.getBitmapCache().getBitmap(uri);
if (bitmap == null) {
URL url = new URL(uri);
bitmap = BitmapFactory.decodeStream(url.openConnection().getInputStream());
WordPress.getBitmapCache().put(uri, bitmap);
}
return bitmap;
}
catch(IOException notFoundException) {
return null;
}
}
@Override
protected void onPostExecute(Bitmap result) {
ImageView imageView = mReference.get();
if (imageView != null) {
if (imageView.getTag() == this) {
imageView.setImageBitmap(result);
fadeInImage(imageView, result);
}
}
}
}
public static Cursor getWordPressMediaImages(String blogId) {
return WordPress.wpDB.getMediaImagesForBlog(blogId);
}
public static Cursor getWordPressMediaVideos(String blogId) {
return WordPress.wpDB.getMediaFilesForBlog(blogId);
}
/**
* Given a media file cursor, returns the thumbnail network URL. Will use photon if available, using the specified
* width.
* @param cursor the media file cursor
* @param width width to use for photon request (if applicable)
*/
public static String getNetworkThumbnailUrl(Cursor cursor, int width) {
String thumbnailURL = cursor.getString(cursor.getColumnIndex(WordPressDB.COLUMN_NAME_THUMBNAIL_URL));
// Allow non-private wp.com and Jetpack blogs to use photon to get a higher res thumbnail
if ((WordPress.getCurrentBlog() != null && WordPress.getCurrentBlog().isPhotonCapable())) {
String imageURL = cursor.getString(cursor.getColumnIndex(WordPressDB.COLUMN_NAME_FILE_URL));
if (imageURL != null) {
thumbnailURL = PhotonUtils.getPhotonImageUrl(imageURL, width, 0);
}
}
return thumbnailURL;
}
/**
* Loads the given network image URL into the {@link NetworkImageView}, using the default {@link ImageLoader}.
*/
public static void loadNetworkImage(String imageUrl, NetworkImageView imageView) {
loadNetworkImage(imageUrl, imageView, WordPress.imageLoader);
}
/**
* Loads the given network image URL into the {@link NetworkImageView}.
*/
public static void loadNetworkImage(String imageUrl, NetworkImageView imageView, ImageLoader imageLoader) {
if (imageUrl != null) {
Uri uri = Uri.parse(imageUrl);
String filepath = uri.getLastPathSegment();
int placeholderResId = WordPressMediaUtils.getPlaceholder(filepath);
imageView.setErrorImageResId(placeholderResId);
// no default image while downloading
imageView.setDefaultImageResId(0);
if (MediaUtils.isValidImage(filepath)) {
imageView.setTag(imageUrl);
imageView.setImageUrl(imageUrl, imageLoader);
} else {
imageView.setImageResource(placeholderResId);
}
} else {
imageView.setImageResource(0);
}
}
/**
* Returns a poster (thumbnail) URL given a VideoPress video URL
* @param videoUrl the remote URL to the VideoPress video
*/
public static String getVideoPressVideoPosterFromURL(String videoUrl) {
String posterUrl = "";
if (videoUrl != null) {
int filetypeLocation = videoUrl.lastIndexOf(".");
if (filetypeLocation > 0) {
posterUrl = videoUrl.substring(0, filetypeLocation) + "_std.original.jpg";
}
}
return posterUrl;
}
}