diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/CameraUtils.java b/cameraview/src/main/java/com/otaliastudios/cameraview/CameraUtils.java index 17e06cf2..ee6e6a73 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/CameraUtils.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/CameraUtils.java @@ -7,7 +7,9 @@ import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Matrix; import android.hardware.Camera; +import android.net.Uri; import android.os.Handler; +import android.os.ParcelFileDescriptor; import com.otaliastudios.cameraview.controls.Facing; import com.otaliastudios.cameraview.engine.mappers.Camera1Mapper; @@ -98,6 +100,23 @@ public class CameraUtils { } } + @SuppressWarnings("WeakerAccess") + @Nullable + @WorkerThread + @SuppressLint("NewApi") + public static Uri writeToFile(Context context, @NonNull final byte[] data, @NonNull Uri file) { + try { + ParcelFileDescriptor fd = context.getContentResolver().openFileDescriptor(file, "w"); + OutputStream stream = new ParcelFileDescriptor.AutoCloseOutputStream(fd); + stream.write(data); + stream.flush(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + return file; + } + } + /** * Writes the given data to the given file in a background thread, returning on the @@ -128,6 +147,26 @@ public class CameraUtils { }); } + @SuppressWarnings("WeakerAccess") + public static void writeToFile(final Context context, + @NonNull final byte[] data, + @NonNull final Uri file, + @NonNull final FileUriCallback callback) { + final Handler ui = new Handler(); + WorkerHandler.execute(new Runnable() { + @Override + public void run() { + final Uri result = writeToFile(context, data, file); + ui.post(new Runnable() { + @Override + public void run() { + callback.onFileReady(result); + } + }); + } + }); + } + /** * Decodes an input byte array and outputs a Bitmap that is ready to be displayed. * The difference with {@link android.graphics.BitmapFactory#decodeByteArray(byte[], int, int)} diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/FileUriCallback.java b/cameraview/src/main/java/com/otaliastudios/cameraview/FileUriCallback.java new file mode 100644 index 00000000..e1a8281c --- /dev/null +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/FileUriCallback.java @@ -0,0 +1,19 @@ +package com.otaliastudios.cameraview; + +import android.net.Uri; + +import androidx.annotation.Nullable; +import androidx.annotation.UiThread; + +public interface FileUriCallback { + /** + * Notifies that the data was succesfully written to file. + * This is run on the UI thread. + * Returns a null object if an exception was encountered, for example + * if you don't have permissions to write to file. + * + * @param fileUri the written file, or null + */ + @UiThread + void onFileReady(@Nullable Uri fileUri); +} diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/PictureResult.java b/cameraview/src/main/java/com/otaliastudios/cameraview/PictureResult.java index 763a81ae..bece92b8 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/PictureResult.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/PictureResult.java @@ -1,7 +1,9 @@ package com.otaliastudios.cameraview; +import android.content.Context; import android.graphics.BitmapFactory; import android.location.Location; +import android.net.Uri; import android.os.Build; import com.otaliastudios.cameraview.controls.Facing; @@ -172,4 +174,8 @@ public class PictureResult { public void toFile(@NonNull File file, @NonNull FileCallback callback) { CameraUtils.writeToFile(getData(), file, callback); } + + public void toFile(Context context, @NonNull Uri fileUri, @NonNull FileUriCallback callback) { + CameraUtils.writeToFile(context, getData(), fileUri, callback); + } }