summaryrefslogtreecommitdiffhomepage
path: root/ui/src/main/java/com/wireguard/android/util/DownloadsFileSaver.java
diff options
context:
space:
mode:
Diffstat (limited to 'ui/src/main/java/com/wireguard/android/util/DownloadsFileSaver.java')
-rw-r--r--ui/src/main/java/com/wireguard/android/util/DownloadsFileSaver.java98
1 files changed, 98 insertions, 0 deletions
diff --git a/ui/src/main/java/com/wireguard/android/util/DownloadsFileSaver.java b/ui/src/main/java/com/wireguard/android/util/DownloadsFileSaver.java
new file mode 100644
index 00000000..7db46fa9
--- /dev/null
+++ b/ui/src/main/java/com/wireguard/android/util/DownloadsFileSaver.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright © 2019 WireGuard LLC. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.wireguard.android.util;
+
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Environment;
+import android.provider.MediaStore;
+import android.provider.MediaStore.MediaColumns;
+
+import com.wireguard.android.R;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+public class DownloadsFileSaver {
+
+ public static class DownloadsFile {
+ private Context context;
+ private OutputStream outputStream;
+ private String fileName;
+ private Uri uri;
+
+ private DownloadsFile(final Context context, final OutputStream outputStream, final String fileName, final Uri uri) {
+ this.context = context;
+ this.outputStream = outputStream;
+ this.fileName = fileName;
+ this.uri = uri;
+ }
+
+ public OutputStream getOutputStream() { return outputStream; }
+ public String getFileName() { return fileName; }
+
+ public void delete() {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
+ context.getContentResolver().delete(uri, null, null);
+ else
+ new File(fileName).delete();
+ }
+ }
+
+ public static DownloadsFile save(final Context context, final String name, final String mimeType, final boolean overwriteExisting) throws Exception {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+ final ContentResolver contentResolver = context.getContentResolver();
+ if (overwriteExisting)
+ contentResolver.delete(MediaStore.Downloads.EXTERNAL_CONTENT_URI, String.format("%s = ?", MediaColumns.DISPLAY_NAME), new String[]{name});
+ final ContentValues contentValues = new ContentValues();
+ contentValues.put(MediaColumns.DISPLAY_NAME, name);
+ contentValues.put(MediaColumns.MIME_TYPE, mimeType);
+ final Uri contentUri = contentResolver.insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, contentValues);
+ if (contentUri == null)
+ throw new IOException(context.getString(R.string.create_downloads_file_error));
+ final OutputStream contentStream = contentResolver.openOutputStream(contentUri);
+ if (contentStream == null)
+ throw new IOException(context.getString(R.string.create_downloads_file_error));
+ @SuppressWarnings("deprecation")
+ Cursor cursor = contentResolver.query(contentUri, new String[]{MediaColumns.DATA}, null, null, null);
+ String path = null;
+ if (cursor != null) {
+ try {
+ if (cursor.moveToFirst())
+ path = cursor.getString(0);
+ } finally {
+ cursor.close();
+ }
+ }
+ if (path == null) {
+ path = "Download/";
+ cursor = contentResolver.query(contentUri, new String[]{MediaColumns.DISPLAY_NAME}, null, null, null);
+ if (cursor != null) {
+ try {
+ if (cursor.moveToFirst())
+ path += cursor.getString(0);
+ } finally {
+ cursor.close();
+ }
+ }
+ }
+ return new DownloadsFile(context, contentStream, path, contentUri);
+ } else {
+ @SuppressWarnings("deprecation")
+ final File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
+ final File file = new File(path, name);
+ if (!path.isDirectory() && !path.mkdirs())
+ throw new IOException(context.getString(R.string.create_output_dir_error));
+ return new DownloadsFile(context, new FileOutputStream(file), file.getAbsolutePath(), null);
+ }
+ }
+}