mirror of
https://github.com/oxen-io/session-android.git
synced 2025-06-09 10:58:34 +00:00
Added ability to save image captures to external storage.
This commit is contained in:
parent
beaa86389d
commit
a210ef3136
BIN
res/drawable-hdpi/ic_download_32.png
Normal file
BIN
res/drawable-hdpi/ic_download_32.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.9 KiB |
BIN
res/drawable-mdpi/ic_download_32.png
Normal file
BIN
res/drawable-mdpi/ic_download_32.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
BIN
res/drawable-xhdpi/ic_download_32.png
Normal file
BIN
res/drawable-xhdpi/ic_download_32.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.1 KiB |
BIN
res/drawable-xxhdpi/ic_download_32.png
Normal file
BIN
res/drawable-xxhdpi/ic_download_32.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.8 KiB |
BIN
res/drawable-xxxhdpi/ic_download_32.png
Normal file
BIN
res/drawable-xxxhdpi/ic_download_32.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.6 KiB |
@ -22,6 +22,7 @@
|
|||||||
android:layout_marginTop="8dp"
|
android:layout_marginTop="8dp"
|
||||||
android:layout_marginEnd="10dp"
|
android:layout_marginEnd="10dp"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
|
android:gravity="center_vertical"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent">
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
@ -41,6 +42,14 @@
|
|||||||
android:padding="8dp"
|
android:padding="8dp"
|
||||||
android:src="@drawable/ic_undo_32" />
|
android:src="@drawable/ic_undo_32" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/scribble_save_button"
|
||||||
|
android:layout_width="42dp"
|
||||||
|
android:layout_height="42dp"
|
||||||
|
android:background="?attr/selectableItemBackgroundBorderless"
|
||||||
|
android:padding="8dp"
|
||||||
|
android:src="@drawable/ic_download_32" />
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/scribble_text_button"
|
android:id="@+id/scribble_text_button"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
@ -779,12 +779,12 @@ public class MediaSendActivity extends PassphraseRequiredActionBarActivity imple
|
|||||||
renderTimer = new Stopwatch("ProcessMedia");
|
renderTimer = new Stopwatch("ProcessMedia");
|
||||||
progressTimer = () -> {
|
progressTimer = () -> {
|
||||||
dialog = new AlertDialog.Builder(new ContextThemeWrapper(MediaSendActivity.this, R.style.TextSecure_MediaSendProgressDialog))
|
dialog = new AlertDialog.Builder(new ContextThemeWrapper(MediaSendActivity.this, R.style.TextSecure_MediaSendProgressDialog))
|
||||||
.setView(R.layout.progress_dialog)
|
.setView(R.layout.progress_dialog)
|
||||||
.setCancelable(false)
|
.setCancelable(false)
|
||||||
.create();
|
.create();
|
||||||
dialog.show();
|
dialog.show();
|
||||||
dialog.getWindow().setLayout(getResources().getDimensionPixelSize(R.dimen.mediasend_progress_dialog_size),
|
dialog.getWindow().setLayout(getResources().getDimensionPixelSize(R.dimen.mediasend_progress_dialog_size),
|
||||||
getResources().getDimensionPixelSize(R.dimen.mediasend_progress_dialog_size));
|
getResources().getDimensionPixelSize(R.dimen.mediasend_progress_dialog_size));
|
||||||
};
|
};
|
||||||
Util.runOnMainDelayed(progressTimer, 250);
|
Util.runOnMainDelayed(progressTimer, 250);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package org.thoughtcrime.securesms.scribbles;
|
package org.thoughtcrime.securesms.scribbles;
|
||||||
|
|
||||||
|
import android.Manifest;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
@ -10,6 +12,7 @@ import androidx.fragment.app.Fragment;
|
|||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.R;
|
import org.thoughtcrime.securesms.R;
|
||||||
import org.thoughtcrime.securesms.imageeditor.ColorableRenderer;
|
import org.thoughtcrime.securesms.imageeditor.ColorableRenderer;
|
||||||
@ -22,9 +25,18 @@ import org.thoughtcrime.securesms.logging.Log;
|
|||||||
import org.thoughtcrime.securesms.mediasend.MediaSendPageFragment;
|
import org.thoughtcrime.securesms.mediasend.MediaSendPageFragment;
|
||||||
import org.thoughtcrime.securesms.mms.MediaConstraints;
|
import org.thoughtcrime.securesms.mms.MediaConstraints;
|
||||||
import org.thoughtcrime.securesms.mms.PushMediaConstraints;
|
import org.thoughtcrime.securesms.mms.PushMediaConstraints;
|
||||||
|
import org.thoughtcrime.securesms.permissions.Permissions;
|
||||||
|
import org.thoughtcrime.securesms.providers.BlobProvider;
|
||||||
import org.thoughtcrime.securesms.scribbles.widget.VerticalSlideColorPicker;
|
import org.thoughtcrime.securesms.scribbles.widget.VerticalSlideColorPicker;
|
||||||
|
import org.thoughtcrime.securesms.util.MediaUtil;
|
||||||
import org.thoughtcrime.securesms.util.ParcelUtil;
|
import org.thoughtcrime.securesms.util.ParcelUtil;
|
||||||
|
import org.thoughtcrime.securesms.util.SaveAttachmentTask;
|
||||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||||
|
import org.thoughtcrime.securesms.util.concurrent.SignalExecutors;
|
||||||
|
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
import static android.app.Activity.RESULT_OK;
|
import static android.app.Activity.RESULT_OK;
|
||||||
|
|
||||||
@ -287,6 +299,36 @@ public final class ImageEditorFragment extends Fragment implements ImageEditorHu
|
|||||||
refreshUniqueColors();
|
refreshUniqueColors();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSave() {
|
||||||
|
SaveAttachmentTask.showWarningDialog(requireContext(), (dialogInterface, i) -> {
|
||||||
|
Permissions.with(this)
|
||||||
|
.request(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE)
|
||||||
|
.ifNecessary()
|
||||||
|
.withPermanentDenialDialog(getString(R.string.MediaPreviewActivity_signal_needs_the_storage_permission_in_order_to_write_to_external_storage_but_it_has_been_permanently_denied))
|
||||||
|
.onAnyDenied(() -> Toast.makeText(requireContext(), R.string.MediaPreviewActivity_unable_to_write_to_external_storage_without_permission, Toast.LENGTH_LONG).show())
|
||||||
|
.onAllGranted(() -> {
|
||||||
|
SimpleTask.run(() -> {
|
||||||
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||||
|
Bitmap image = imageEditorView.getModel().render(requireContext());
|
||||||
|
|
||||||
|
image.compress(Bitmap.CompressFormat.JPEG, 80, outputStream);
|
||||||
|
|
||||||
|
return BlobProvider.getInstance()
|
||||||
|
.forData(outputStream.toByteArray())
|
||||||
|
.withMimeType(MediaUtil.IMAGE_JPEG)
|
||||||
|
.createForSingleUseInMemory();
|
||||||
|
|
||||||
|
}, uri -> {
|
||||||
|
SaveAttachmentTask saveTask = new SaveAttachmentTask(requireContext());
|
||||||
|
SaveAttachmentTask.Attachment attachment = new SaveAttachmentTask.Attachment(uri, MediaUtil.IMAGE_JPEG, System.currentTimeMillis(), null);
|
||||||
|
saveTask.executeOnExecutor(SignalExecutors.BOUNDED, attachment);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.execute();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFlipHorizontal() {
|
public void onFlipHorizontal() {
|
||||||
imageEditorView.getModel().flipHorizontal();
|
imageEditorView.getModel().flipHorizontal();
|
||||||
|
@ -36,6 +36,7 @@ public final class ImageEditorHud extends LinearLayout {
|
|||||||
private View textButton;
|
private View textButton;
|
||||||
private View stickerButton;
|
private View stickerButton;
|
||||||
private View undoButton;
|
private View undoButton;
|
||||||
|
private View saveButton;
|
||||||
private View deleteButton;
|
private View deleteButton;
|
||||||
private View confirmButton;
|
private View confirmButton;
|
||||||
private VerticalSlideColorPicker colorPicker;
|
private VerticalSlideColorPicker colorPicker;
|
||||||
@ -81,6 +82,7 @@ public final class ImageEditorHud extends LinearLayout {
|
|||||||
textButton = findViewById(R.id.scribble_text_button);
|
textButton = findViewById(R.id.scribble_text_button);
|
||||||
stickerButton = findViewById(R.id.scribble_sticker_button);
|
stickerButton = findViewById(R.id.scribble_sticker_button);
|
||||||
undoButton = findViewById(R.id.scribble_undo_button);
|
undoButton = findViewById(R.id.scribble_undo_button);
|
||||||
|
saveButton = findViewById(R.id.scribble_save_button);
|
||||||
deleteButton = findViewById(R.id.scribble_delete_button);
|
deleteButton = findViewById(R.id.scribble_delete_button);
|
||||||
confirmButton = findViewById(R.id.scribble_confirm_button);
|
confirmButton = findViewById(R.id.scribble_confirm_button);
|
||||||
colorPicker = findViewById(R.id.scribble_color_picker);
|
colorPicker = findViewById(R.id.scribble_color_picker);
|
||||||
@ -100,7 +102,7 @@ public final class ImageEditorHud extends LinearLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void initializeVisibilityMap() {
|
private void initializeVisibilityMap() {
|
||||||
setVisibleViewsWhenInMode(Mode.NONE, drawButton, highlightButton, textButton, stickerButton, cropButton, undoButton);
|
setVisibleViewsWhenInMode(Mode.NONE, drawButton, highlightButton, textButton, stickerButton, cropButton, undoButton, saveButton);
|
||||||
|
|
||||||
setVisibleViewsWhenInMode(Mode.DRAW, confirmButton, undoButton, colorPicker, colorPalette);
|
setVisibleViewsWhenInMode(Mode.DRAW, confirmButton, undoButton, colorPicker, colorPalette);
|
||||||
|
|
||||||
@ -145,6 +147,7 @@ public final class ImageEditorHud extends LinearLayout {
|
|||||||
highlightButton.setOnClickListener(v -> setMode(Mode.HIGHLIGHT));
|
highlightButton.setOnClickListener(v -> setMode(Mode.HIGHLIGHT));
|
||||||
textButton.setOnClickListener(v -> setMode(Mode.TEXT));
|
textButton.setOnClickListener(v -> setMode(Mode.TEXT));
|
||||||
stickerButton.setOnClickListener(v -> setMode(Mode.MOVE_DELETE));
|
stickerButton.setOnClickListener(v -> setMode(Mode.MOVE_DELETE));
|
||||||
|
saveButton.setOnClickListener(v -> eventListener.onSave());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setColorPalette(@NonNull Set<Integer> colors) {
|
public void setColorPalette(@NonNull Set<Integer> colors) {
|
||||||
@ -241,6 +244,7 @@ public final class ImageEditorHud extends LinearLayout {
|
|||||||
void onColorChange(int color);
|
void onColorChange(int color);
|
||||||
void onUndo();
|
void onUndo();
|
||||||
void onDelete();
|
void onDelete();
|
||||||
|
void onSave();
|
||||||
void onFlipHorizontal();
|
void onFlipHorizontal();
|
||||||
void onRotate90AntiClockwise();
|
void onRotate90AntiClockwise();
|
||||||
void onCropAspectLock(boolean locked);
|
void onCropAspectLock(boolean locked);
|
||||||
@ -266,6 +270,10 @@ public final class ImageEditorHud extends LinearLayout {
|
|||||||
public void onDelete() {
|
public void onDelete() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSave() {
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFlipHorizontal() {
|
public void onFlipHorizontal() {
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user