private String uploadImageFile(Map<String, Object> pictureParams, MediaFile mf, Blog blog) { // create temporary upload file File tempFile; try { String fileExtension = MimeTypeMap.getFileExtensionFromUrl(mf.getFileName()); tempFile = createTempUploadFile(fileExtension); } catch (IOException e) { mIsMediaError = true; mErrorMessage = mContext.getString(R.string.file_not_found); return null; } Object[] params = {1, blog.getUsername(), blog.getPassword(), pictureParams}; Object result = uploadFileHelper(params, tempFile); if (result == null) { mIsMediaError = true; return null; } Map<?, ?> contentHash = (HashMap<?, ?>) result; String pictureURL = contentHash.get("url").toString(); if (mf.isFeatured()) { try { if (contentHash.get("id") != null) { featuredImageID = Integer.parseInt(contentHash.get("id").toString()); if (!mf.isFeaturedInPost()) return ""; } } catch (NumberFormatException e) { AppLog.e(T.POSTS, e); } } return pictureURL; }
private WPEditImageSpan createWPEditImageSpanRemote(Context context, MediaFile mediaFile) { int drawable = mediaFile.isVideo() ? R.drawable.media_movieclip : R.drawable.legacy_dashicon_format_image_big_grey; Uri uri = Uri.parse(mediaFile.getFileURL()); WPEditImageSpan imageSpan = new WPEditImageSpan(context, drawable, uri); imageSpan.setMediaFile(mediaFile); return imageSpan; }
private WPEditImageSpan createWPEditImageSpan(Context context, MediaFile mediaFile) { if (!URLUtil.isNetworkUrl(mediaFile.getFileURL())) { return createWPEditImageSpanLocal(context, mediaFile); } else { return createWPEditImageSpanRemote(context, mediaFile); } }
private WPEditImageSpan createWPEditImageSpanLocal(Context context, MediaFile mediaFile) { Uri imageUri = Uri.parse(mediaFile.getFilePath()); Bitmap thumbnailBitmap; if (MediaUtils.isVideo(imageUri.toString())) { thumbnailBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.media_movieclip); } else { thumbnailBitmap = ImageUtils.getWPImageSpanThumbnailFromFilePath( context, imageUri.getEncodedPath(), ImageUtils.getMaximumThumbnailWidthForEditor(context)); if (thumbnailBitmap == null) { // Use a placeholder in case thumbnail can't be decoded (OOM for instance) thumbnailBitmap = BitmapFactory.decodeResource( context.getResources(), R.drawable.legacy_dashicon_format_image_big_grey); } } WPEditImageSpan imageSpan = new WPEditImageSpan(context, thumbnailBitmap, imageUri); mediaFile.setWidth( MediaUtils.getMinimumImageWidth(context, imageUri, mBlogSettingMaxImageWidth)); return imageSpan; }
@Override public boolean onTouch(View v, MotionEvent event) { float pos = event.getY(); if (event.getAction() == 0) mLastYPos = pos; if (event.getAction() > 1) { int scrollThreshold = DisplayUtils.dpToPx(getActivity(), 2); if (((mLastYPos - pos) > scrollThreshold) || ((pos - mLastYPos) > scrollThreshold)) mScrollDetected = true; } mLastYPos = pos; if (event.getAction() == MotionEvent.ACTION_UP) { ActionBar actionBar = getActionBar(); if (actionBar != null && actionBar.isShowing()) { setContentEditingModeVisible(true); return false; } } if (event.getAction() == MotionEvent.ACTION_UP && !mScrollDetected) { Layout layout = ((TextView) v).getLayout(); int x = (int) event.getX(); int y = (int) event.getY(); x += v.getScrollX(); y += v.getScrollY(); if (layout != null) { int line = layout.getLineForVertical(y); int charPosition = layout.getOffsetForHorizontal(line, x); Spannable spannable = mContentEditText.getText(); if (spannable == null) { return false; } // check if image span was tapped WPImageSpan[] imageSpans = spannable.getSpans(charPosition, charPosition, WPImageSpan.class); if (imageSpans.length != 0) { final WPImageSpan imageSpan = imageSpans[0]; MediaFile mediaFile = imageSpan.getMediaFile(); if (mediaFile == null) return false; if (!mediaFile.isVideo()) { LayoutInflater factory = LayoutInflater.from(getActivity()); final View alertView = factory.inflate(R.layout.alert_image_options, null); if (alertView == null) return false; final EditText imageWidthText = (EditText) alertView.findViewById(R.id.imageWidthText); final EditText titleText = (EditText) alertView.findViewById(R.id.title); final EditText caption = (EditText) alertView.findViewById(R.id.caption); final CheckBox featuredCheckBox = (CheckBox) alertView.findViewById(R.id.featuredImage); final CheckBox featuredInPostCheckBox = (CheckBox) alertView.findViewById(R.id.featuredInPost); // show featured image checkboxes if supported if (mFeaturedImageSupported) { featuredCheckBox.setVisibility(View.VISIBLE); featuredInPostCheckBox.setVisibility(View.VISIBLE); } featuredCheckBox.setOnCheckedChangeListener( new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if (isChecked) { featuredInPostCheckBox.setVisibility(View.VISIBLE); } else { featuredInPostCheckBox.setVisibility(View.GONE); } } }); final SeekBar seekBar = (SeekBar) alertView.findViewById(R.id.imageWidth); final Spinner alignmentSpinner = (Spinner) alertView.findViewById(R.id.alignment_spinner); ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource( getActivity(), R.array.alignment_array, android.R.layout.simple_spinner_item); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); alignmentSpinner.setAdapter(adapter); imageWidthText.setText(String.valueOf(mediaFile.getWidth()) + "px"); seekBar.setProgress(mediaFile.getWidth()); titleText.setText(mediaFile.getTitle()); caption.setText(mediaFile.getCaption()); featuredCheckBox.setChecked(mediaFile.isFeatured()); if (mediaFile.isFeatured()) { featuredInPostCheckBox.setVisibility(View.VISIBLE); } else { featuredInPostCheckBox.setVisibility(View.GONE); } featuredInPostCheckBox.setChecked(mediaFile.isFeaturedInPost()); alignmentSpinner.setSelection(mediaFile.getHorizontalAlignment(), true); final int maxWidth = MediaUtils.getMinimumImageWidth( getActivity(), imageSpan.getImageSource(), mBlogSettingMaxImageWidth); seekBar.setMax(maxWidth / 10); if (mediaFile.getWidth() != 0) { seekBar.setProgress(mediaFile.getWidth() / 10); } seekBar.setOnSeekBarChangeListener( new SeekBar.OnSeekBarChangeListener() { @Override public void onStopTrackingTouch(SeekBar seekBar) {} @Override public void onStartTrackingTouch(SeekBar seekBar) {} @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { if (progress == 0) { progress = 1; } imageWidthText.setText(progress * 10 + "px"); } }); imageWidthText.setOnFocusChangeListener( new View.OnFocusChangeListener() { @Override public void onFocusChange(View v, boolean hasFocus) { if (hasFocus) { imageWidthText.setText(""); } } }); imageWidthText.setOnEditorActionListener( new TextView.OnEditorActionListener() { @Override public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { int width = getEditTextIntegerClamped(imageWidthText, 10, maxWidth); seekBar.setProgress(width / 10); imageWidthText.setSelection((String.valueOf(width).length())); InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow( imageWidthText.getWindowToken(), InputMethodManager.RESULT_UNCHANGED_SHOWN); return true; } }); showImageSettings( alertView, titleText, caption, imageWidthText, featuredCheckBox, featuredInPostCheckBox, maxWidth, alignmentSpinner, imageSpan); mScrollDetected = false; return true; } } else { mContentEditText.setMovementMethod(ArrowKeyMovementMethod.getInstance()); int selectionStart = mContentEditText.getSelectionStart(); if (selectionStart >= 0 && mContentEditText.getSelectionEnd() >= selectionStart) mContentEditText.setSelection(selectionStart, mContentEditText.getSelectionEnd()); } // get media gallery spans MediaGalleryImageSpan[] gallerySpans = spannable.getSpans(charPosition, charPosition, MediaGalleryImageSpan.class); if (gallerySpans.length > 0) { final MediaGalleryImageSpan gallerySpan = gallerySpans[0]; Intent intent = new Intent(ACTION_MEDIA_GALLERY_TOUCHED); intent.putExtra(EXTRA_MEDIA_GALLERY, gallerySpan.getMediaGallery()); getActivity().sendBroadcast(intent); } } } else if (event.getAction() == 1) { mScrollDetected = false; } return false; }
public void addMediaFile( final MediaFile mediaFile, final String imageUrl, final ImageLoader imageLoader, final int start, final int end) { mediaFile.setFileURL(imageUrl); mediaFile.setFilePath(imageUrl); final WPEditImageSpan imageSpan = createWPEditImageSpan(getActivity(), mediaFile); mEditorFragmentListener.saveMediaFile(mediaFile); imageSpan.setMediaFile(mediaFile); Handler handler = new Handler(Looper.getMainLooper()); final Runnable r = new Runnable() { @Override public void run() { // Insert the WPImageSpan in the content field int selectionStart = start; int selectionEnd = end; if (selectionStart > selectionEnd) { int temp = selectionEnd; selectionEnd = selectionStart; selectionStart = temp; } imageSpan.setPosition(selectionStart, selectionEnd); int line, column = 0; if (mContentEditText.getLayout() != null) { line = mContentEditText.getLayout().getLineForOffset(selectionStart); column = selectionStart - mContentEditText.getLayout().getLineStart(line); } Editable s = mContentEditText.getText(); if (s == null) { return; } WPImageSpan[] imageSpans = s.getSpans(selectionStart, selectionEnd, WPImageSpan.class); if (imageSpans.length != 0) { // insert a few line breaks if the cursor is already on an image s.insert(selectionEnd, "\n\n"); selectionStart = selectionStart + 2; selectionEnd = selectionEnd + 2; } else if (column != 0) { // insert one line break if the cursor is not at the first column s.insert(selectionEnd, "\n"); selectionStart = selectionStart + 1; selectionEnd = selectionEnd + 1; } s.insert(selectionStart, " "); s.setSpan( imageSpan, selectionStart, selectionEnd + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); AlignmentSpan.Standard as = new AlignmentSpan.Standard(Layout.Alignment.ALIGN_CENTER); s.setSpan(as, selectionStart, selectionEnd + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); s.insert(selectionEnd + 1, "\n\n"); // Fetch and replace the WPImageSpan if it's a remote media if (imageLoader != null && URLUtil.isNetworkUrl(imageUrl)) { loadWPImageSpanThumbnail(mediaFile, imageUrl, imageLoader); } } }; handler.postDelayed(r, 1); }
private void loadWPImageSpanThumbnail( MediaFile mediaFile, String imageURL, ImageLoader imageLoader) { if (mediaFile == null || imageURL == null) { return; } final String mediaId = mediaFile.getMediaId(); if (mediaId == null) { return; } final int maxThumbWidth = ImageUtils.getMaximumThumbnailWidthForEditor(getActivity()); imageLoader.get( imageURL, new ImageLoader.ImageListener() { @Override public void onErrorResponse(VolleyError arg0) {} @Override public void onResponse(ImageLoader.ImageContainer container, boolean arg1) { Bitmap downloadedBitmap = container.getBitmap(); if (downloadedBitmap == null) { // no bitmap downloaded from the server. return; } if (downloadedBitmap.getWidth() < MIN_THUMBNAIL_WIDTH) { // Picture is too small. Show the placeholder in this case. return; } Bitmap resizedBitmap; // resize the downloaded bitmap resizedBitmap = ImageUtils.getScaledBitmapAtLongestSide(downloadedBitmap, maxThumbWidth); if (resizedBitmap == null) { return; } final EditText editText = mContentEditText; Editable s = editText.getText(); if (s == null) { return; } WPImageSpan[] spans = s.getSpans(0, s.length(), WPImageSpan.class); if (spans.length != 0 && getActivity() != null) { for (WPImageSpan is : spans) { MediaFile mediaFile = is.getMediaFile(); if (mediaFile == null) { continue; } if (mediaId.equals(mediaFile.getMediaId()) && !is.isNetworkImageLoaded()) { // replace the existing span with a new one with the correct image, re-add // it to the same position. int spanStart = is.getStartPosition(); int spanEnd = is.getEndPosition(); WPEditImageSpan imageSpan = new WPEditImageSpan(getActivity(), resizedBitmap, is.getImageSource()); imageSpan.setMediaFile(is.getMediaFile()); imageSpan.setNetworkImageLoaded(true); imageSpan.setPosition(spanStart, spanEnd); s.removeSpan(is); s.setSpan(imageSpan, spanStart, spanEnd + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); break; } } } } }, 0, 0); }
private String uploadVideo(MediaFile mediaFile) { // create temp file for media upload String tempFileName = "wp-" + System.currentTimeMillis(); try { mContext.openFileOutput(tempFileName, Context.MODE_PRIVATE); } catch (FileNotFoundException e) { mErrorMessage = getResources().getString(R.string.file_error_create); return null; } if (mediaFile.getFilePath() == null) { mErrorMessage = mContext.getString(R.string.error_media_upload); return null; } Uri videoUri = Uri.parse(mediaFile.getFilePath()); File videoFile = null; String mimeType = "", xRes = "", yRes = ""; if (videoUri.toString().contains("content:")) { String[] projection = new String[] { Video.Media._ID, Video.Media.DATA, Video.Media.MIME_TYPE, Video.Media.RESOLUTION }; Cursor cur = mContext.getContentResolver().query(videoUri, projection, null, null, null); if (cur != null && cur.moveToFirst()) { int dataColumn = cur.getColumnIndex(Video.Media.DATA); int mimeTypeColumn = cur.getColumnIndex(Video.Media.MIME_TYPE); int resolutionColumn = cur.getColumnIndex(Video.Media.RESOLUTION); mediaFile = new MediaFile(); String thumbData = cur.getString(dataColumn); mimeType = cur.getString(mimeTypeColumn); videoFile = new File(thumbData); mediaFile.setFilePath(videoFile.getPath()); String resolution = cur.getString(resolutionColumn); if (resolution != null) { String[] resolutions = resolution.split("x"); if (resolutions.length >= 2) { xRes = resolutions[0]; yRes = resolutions[1]; } } else { // set the width of the video to the thumbnail width, else 640x480 if (!mBlog.getMaxImageWidth().equals("Original Size")) { xRes = mBlog.getMaxImageWidth(); yRes = String.valueOf(Math.round(Integer.valueOf(mBlog.getMaxImageWidth()) * 0.75)); } else { xRes = "640"; yRes = "480"; } } } } else { // file is not in media library String filePath = videoUri.toString().replace("file://", ""); mediaFile.setFilePath(filePath); videoFile = new File(filePath); } if (videoFile == null) { mErrorMessage = mContext.getResources().getString(R.string.error_media_upload); return null; } if (TextUtils.isEmpty(mimeType)) { mimeType = MediaUtils.getMediaFileMimeType(videoFile); } String videoName = MediaUtils.getMediaFileName(videoFile, mimeType); // try to upload the video Map<String, Object> m = new HashMap<String, Object>(); m.put("name", videoName); m.put("type", mimeType); m.put("bits", mediaFile); m.put("overwrite", true); Object[] params = {1, mBlog.getUsername(), mBlog.getPassword(), m}; FeatureSet featureSet = synchronousGetFeatureSet(); boolean selfHosted = WordPress.currentBlog != null && !WordPress.currentBlog.isDotcomFlag(); boolean isVideoEnabled = selfHosted || (featureSet != null && mFeatureSet.isVideopressEnabled()); if (isVideoEnabled) { File tempFile; try { String fileExtension = MimeTypeMap.getFileExtensionFromUrl(videoName); tempFile = createTempUploadFile(fileExtension); } catch (IOException e) { mErrorMessage = getResources().getString(R.string.file_error_create); return null; } Object result = uploadFileHelper(params, tempFile); Map<?, ?> resultMap = (HashMap<?, ?>) result; if (resultMap != null && resultMap.containsKey("url")) { String resultURL = resultMap.get("url").toString(); if (resultMap.containsKey(MediaFile.VIDEOPRESS_SHORTCODE_ID)) { resultURL = resultMap.get(MediaFile.VIDEOPRESS_SHORTCODE_ID).toString() + "\n"; } else { resultURL = String.format( "<video width=\"%s\" height=\"%s\" controls=\"controls\"><source src=\"%s\" type=\"%s\" /><a href=\"%s\">Click to view video</a>.</video>", xRes, yRes, resultURL, mimeType, resultURL); } return resultURL; } else { mErrorMessage = mContext.getResources().getString(R.string.error_media_upload); return null; } } else { mErrorMessage = getString(R.string.media_no_video_message); mErrorUnavailableVideoPress = true; return null; } }
private String uploadImage(MediaFile mediaFile) { AppLog.d(T.POSTS, "uploadImage: " + mediaFile.getFilePath()); if (mediaFile.getFilePath() == null) { return null; } Uri imageUri = Uri.parse(mediaFile.getFilePath()); File imageFile = null; String mimeType = "", path = ""; if (imageUri.toString().contains("content:")) { String[] projection = new String[] {Images.Media._ID, Images.Media.DATA, Images.Media.MIME_TYPE}; Cursor cur = mContext.getContentResolver().query(imageUri, projection, null, null, null); if (cur != null && cur.moveToFirst()) { int dataColumn = cur.getColumnIndex(Images.Media.DATA); int mimeTypeColumn = cur.getColumnIndex(Images.Media.MIME_TYPE); String thumbData = cur.getString(dataColumn); mimeType = cur.getString(mimeTypeColumn); imageFile = new File(thumbData); path = thumbData; mediaFile.setFilePath(imageFile.getPath()); } } else { // file is not in media library path = imageUri.toString().replace("file://", ""); imageFile = new File(path); mediaFile.setFilePath(path); } // check if the file exists if (imageFile == null) { mErrorMessage = mContext.getString(R.string.file_not_found); return null; } if (TextUtils.isEmpty(mimeType)) { mimeType = MediaUtils.getMediaFileMimeType(imageFile); } String fileName = MediaUtils.getMediaFileName(imageFile, mimeType); String fileExtension = MimeTypeMap.getFileExtensionFromUrl(fileName).toLowerCase(); int orientation = ImageUtils.getImageOrientation(mContext, path); String resizedPictureURL = null; // We need to upload a resized version of the picture when the blog settings != original size, // or when // the user has selected a smaller size for the current picture in the picture settings screen // We won't resize gif images to keep them awesome. boolean shouldUploadResizedVersion = false; // If it's not a gif and blog don't keep original size, there is a chance we need to resize if (!mimeType.equals("image/gif") && !mBlog.getMaxImageWidth().equals("Original Size")) { // check the picture settings int pictureSettingWidth = mediaFile.getWidth(); BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(path, options); int imageHeight = options.outHeight; int imageWidth = options.outWidth; int[] dimensions = {imageWidth, imageHeight}; if (dimensions[0] != 0 && dimensions[0] != pictureSettingWidth) { shouldUploadResizedVersion = true; } } boolean shouldAddImageWidthCSS = false; if (shouldUploadResizedVersion) { MediaFile resizedMediaFile = new MediaFile(mediaFile); // Create resized image byte[] bytes = ImageUtils.createThumbnailFromUri( mContext, imageUri, resizedMediaFile.getWidth(), fileExtension, orientation); if (bytes == null) { // We weren't able to resize the image, so we will upload the full size image with css to // resize it shouldUploadResizedVersion = false; shouldAddImageWidthCSS = true; } else { // Save temp image String tempFilePath; File resizedImageFile; try { resizedImageFile = File.createTempFile("wp-image-", fileExtension); FileOutputStream out = new FileOutputStream(resizedImageFile); out.write(bytes); out.close(); tempFilePath = resizedImageFile.getPath(); } catch (IOException e) { AppLog.w(T.POSTS, "failed to create image temp file"); mErrorMessage = mContext.getString(R.string.error_media_upload); return null; } // upload resized picture if (!TextUtils.isEmpty(tempFilePath)) { resizedMediaFile.setFilePath(tempFilePath); Map<String, Object> parameters = new HashMap<String, Object>(); parameters.put("name", fileName); parameters.put("type", mimeType); parameters.put("bits", resizedMediaFile); parameters.put("overwrite", true); resizedPictureURL = uploadImageFile(parameters, resizedMediaFile, mBlog); if (resizedPictureURL == null) { AppLog.w(T.POSTS, "failed to upload resized picture"); return null; } else if (resizedImageFile.exists()) { resizedImageFile.delete(); } } else { AppLog.w(T.POSTS, "failed to create resized picture"); mErrorMessage = mContext.getString(R.string.out_of_memory); return null; } } } String fullSizeUrl = null; // Upload the full size picture if "Original Size" is selected in settings, // or if 'link to full size' is checked. if (!shouldUploadResizedVersion || mBlog.isFullSizeImage()) { Map<String, Object> parameters = new HashMap<String, Object>(); parameters.put("name", fileName); parameters.put("type", mimeType); parameters.put("bits", mediaFile); parameters.put("overwrite", true); fullSizeUrl = uploadImageFile(parameters, mediaFile, mBlog); if (fullSizeUrl == null) { mErrorMessage = mContext.getString(R.string.error_media_upload); return null; } } return mediaFile.getImageHtmlForUrls(fullSizeUrl, resizedPictureURL, shouldAddImageWidthCSS); }
/** Finds media in post content, uploads them, and returns the HTML to insert in the post */ private String processPostMedia(String postContent) { String imageTagsPattern = "<img[^>]+android-uri\\s*=\\s*['\"]([^'\"]+)['\"][^>]*>"; Pattern pattern = Pattern.compile(imageTagsPattern); Matcher matcher = pattern.matcher(postContent); int totalMediaItems = 0; List<String> imageTags = new ArrayList<String>(); while (matcher.find()) { imageTags.add(matcher.group()); totalMediaItems++; } mPostUploadNotifier.setTotalMediaItems(totalMediaItems); int mediaItemCount = 0; for (String tag : imageTags) { Pattern p = Pattern.compile("android-uri=\"([^\"]+)\""); Matcher m = p.matcher(tag); if (m.find()) { String imageUri = m.group(1); if (!imageUri.equals("")) { MediaFile mediaFile = WordPress.wpDB.getMediaFile(imageUri, mPost); if (mediaFile != null) { // Get image thumbnail for notification icon Bitmap imageIcon = ImageUtils.getWPImageSpanThumbnailFromFilePath( mContext, imageUri, DisplayUtils.dpToPx(mContext, 128)); // Crop the thumbnail to be squared in the center if (imageIcon != null) { int squaredSize = DisplayUtils.dpToPx(mContext, 64); imageIcon = ThumbnailUtils.extractThumbnail(imageIcon, squaredSize, squaredSize); mLatestIcon = imageIcon; } mediaItemCount++; mPostUploadNotifier.setCurrentMediaItem(mediaItemCount); mPostUploadNotifier.updateNotificationIcon(imageIcon); String mediaUploadOutput; if (mediaFile.isVideo()) { mHasVideo = true; mediaUploadOutput = uploadVideo(mediaFile); } else { mHasImage = true; mediaUploadOutput = uploadImage(mediaFile); } if (mediaUploadOutput != null) { postContent = postContent.replace(tag, mediaUploadOutput); } else { postContent = postContent.replace(tag, ""); mIsMediaError = true; } } } } } return postContent; }