Make UniFile actually backed by ParcelFileDescriptor, implement IO stream as extensions, Resolve #896
This commit is contained in:
1 parent
24ccf60870
commit
3973f5ef70
12 files changed
+82
-276
No files matched your search
@@ -17,6 +17,7 @@ package com.hippo.ehviewer.gallery
|
||||
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import android.os.ParcelFileDescriptor
|
||||
import com.hippo.UriArchiveAccessor
|
||||
import com.hippo.ehviewer.Settings
|
||||
import com.hippo.image.Image
|
||||
@@ -35,7 +36,6 @@ import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.Semaphore
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
import kotlinx.coroutines.sync.withPermit
|
||||
import java.io.FileOutputStream
|
||||
import java.io.IOException
|
||||
|
||||
class ArchivePageLoader(context: Context, uri: Uri, passwdFlow: Flow<String>) : PageLoader2(),
|
||||
@@ -137,16 +137,16 @@ class ArchivePageLoader(context: Context, uri: Uri, passwdFlow: Flow<String>) :
|
||||
}
|
||||
|
||||
override fun save(index: Int, file: UniFile): Boolean {
|
||||
val stream: FileOutputStream
|
||||
val fd: ParcelFileDescriptor
|
||||
try {
|
||||
stream = file.openOutputStream() as FileOutputStream
|
||||
fd = file.openFileDescriptor("w")
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
return false
|
||||
}
|
||||
archiveAccessor.extractToFd(index, stream.fd)
|
||||
archiveAccessor.extractToFd(index, fd.fileDescriptor)
|
||||
try {
|
||||
stream.close()
|
||||
fd.close()
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
return false
|
||||
|
||||
@@ -37,6 +37,8 @@ import com.hippo.ehviewer.gallery.SUPPORT_IMAGE_EXTENSIONS
|
||||
import com.hippo.image.Image.CloseableSource
|
||||
import com.hippo.unifile.RawFile
|
||||
import com.hippo.unifile.UniFile
|
||||
import com.hippo.unifile.openInputStream
|
||||
import com.hippo.unifile.openOutputStream
|
||||
import com.hippo.yorozuya.FileUtils
|
||||
import com.hippo.yorozuya.MathUtils
|
||||
import kotlinx.coroutines.currentCoroutineContext
|
||||
@@ -117,9 +119,9 @@ class SpiderDen(private val mGalleryInfo: GalleryInfo) {
|
||||
sCache.read(key) {
|
||||
val extension = fixExtension("." + metadata.toFile().readText())
|
||||
val file = dir.createFile(generateImageFilename(index, extension)) ?: return false
|
||||
(file.openOutputStream() as FileOutputStream).use { outputStream ->
|
||||
file.openFileDescriptor("w").use { outFd ->
|
||||
ParcelFileDescriptor.open(data.toFile(), MODE_READ_WRITE).use {
|
||||
it sendTo outputStream.fd
|
||||
it sendTo outFd
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -199,7 +201,7 @@ class SpiderDen(private val mGalleryInfo: GalleryInfo) {
|
||||
|
||||
findDownloadFileForIndex(index, extension)?.runSuspendCatching {
|
||||
openOutputStream().use { outputStream ->
|
||||
(outputStream as FileOutputStream).channel.use { return doSave(it) == length }
|
||||
outputStream.channel.use { return doSave(it) == length }
|
||||
}
|
||||
}?.onFailure {
|
||||
it.printStackTrace()
|
||||
@@ -254,7 +256,7 @@ class SpiderDen(private val mGalleryInfo: GalleryInfo) {
|
||||
downloadDir?.let { uniFile ->
|
||||
runCatching {
|
||||
findImageFile(uniFile, index)?.openInputStream()?.use {
|
||||
copy(it as FileInputStream)
|
||||
copy(it)
|
||||
}
|
||||
}.onFailure {
|
||||
it.printStackTrace()
|
||||
|
||||
@@ -4,6 +4,8 @@ import coil.disk.DiskCache
|
||||
import com.hippo.compat.readLegacySpiderInfo
|
||||
import com.hippo.ehviewer.EhApplication
|
||||
import com.hippo.unifile.UniFile
|
||||
import com.hippo.unifile.openInputStream
|
||||
import com.hippo.unifile.openOutputStream
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.cbor.Cbor
|
||||
import kotlinx.serialization.decodeFromByteArray
|
||||
|
||||
@@ -18,11 +18,11 @@ package com.hippo.ehviewer.ui
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import android.os.ParcelFileDescriptor
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.hippo.app.ListCheckBoxDialogBuilder
|
||||
import com.hippo.ehviewer.EhApplication.Companion.application
|
||||
import com.hippo.ehviewer.download.DownloadManager as downloadManager
|
||||
import com.hippo.ehviewer.EhApplication.Companion.favouriteStatusRouter
|
||||
import com.hippo.ehviewer.EhDB
|
||||
import com.hippo.ehviewer.R
|
||||
@@ -36,7 +36,7 @@ import com.hippo.unifile.UniFile
|
||||
import com.hippo.yorozuya.IOUtils
|
||||
import com.hippo.yorozuya.collect.LongList
|
||||
import java.io.IOException
|
||||
import java.io.InputStream
|
||||
import com.hippo.ehviewer.download.DownloadManager as downloadManager
|
||||
|
||||
object CommonOperations {
|
||||
private fun doAddToFavorites(
|
||||
@@ -227,9 +227,9 @@ object CommonOperations {
|
||||
return
|
||||
}
|
||||
val noMedia = file.createFile(".nomedia") ?: return
|
||||
var `is`: InputStream? = null
|
||||
var `is`: ParcelFileDescriptor? = null
|
||||
try {
|
||||
`is` = noMedia.openInputStream()
|
||||
`is` = noMedia.openFileDescriptor("r")
|
||||
} catch (e: IOException) {
|
||||
// Ignore
|
||||
} finally {
|
||||
|
||||
@@ -21,14 +21,13 @@ import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.ImageDecoder;
|
||||
import android.net.Uri;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.hippo.image.Image;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
final class Contracts {
|
||||
private Contracts() {
|
||||
@@ -80,45 +79,12 @@ final class Contracts {
|
||||
}
|
||||
|
||||
@NonNull
|
||||
static OutputStream openOutputStream(Context context, Uri uri) throws IOException {
|
||||
try {
|
||||
OutputStream os = context.getContentResolver().openOutputStream(uri);
|
||||
if (os == null) {
|
||||
throw new IOException("Can't open OutputStream");
|
||||
}
|
||||
return os;
|
||||
} catch (Throwable e) {
|
||||
Utils.throwIfFatal(e);
|
||||
throw new IOException("Can't open OutputStream", e);
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
static OutputStream openOutputStream(Context context, Uri uri, boolean append) throws IOException {
|
||||
try {
|
||||
OutputStream os = context.getContentResolver().openOutputStream(uri, append ? "wa" : "w");
|
||||
if (os == null) {
|
||||
throw new IOException("Can't open OutputStream");
|
||||
}
|
||||
return os;
|
||||
} catch (Throwable e) {
|
||||
Utils.throwIfFatal(e);
|
||||
throw new IOException("Can't open OutputStream", e);
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
static InputStream openInputStream(Context context, Uri uri) throws IOException {
|
||||
try {
|
||||
InputStream is = context.getContentResolver().openInputStream(uri);
|
||||
if (is == null) {
|
||||
throw new IOException("Can't open InputStream");
|
||||
}
|
||||
return is;
|
||||
} catch (Throwable e) {
|
||||
Utils.throwIfFatal(e);
|
||||
throw new IOException("Can't open InputStream", e);
|
||||
static ParcelFileDescriptor openFileDescriptor(Context context, Uri uri, String mode) throws IOException {
|
||||
ParcelFileDescriptor pfd = context.getContentResolver().openFileDescriptor(uri, mode);
|
||||
if (pfd == null) {
|
||||
throw new IOException("Can't open ParcelFileDescriptor");
|
||||
}
|
||||
return pfd;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
|
||||
@@ -18,14 +18,13 @@ package com.hippo.unifile;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.hippo.image.Image;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
class MediaFile extends UniFile {
|
||||
|
||||
@@ -76,14 +75,7 @@ class MediaFile extends UniFile {
|
||||
|
||||
@Override
|
||||
public boolean isFile() {
|
||||
InputStream is;
|
||||
try {
|
||||
is = openInputStream();
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
}
|
||||
Utils.closeQuietly(is);
|
||||
return true;
|
||||
return DocumentsContractApi19.isFile(mContext, mUri);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -103,13 +95,12 @@ class MediaFile extends UniFile {
|
||||
|
||||
@Override
|
||||
public boolean canWrite() {
|
||||
OutputStream os;
|
||||
try {
|
||||
os = openOutputStream(true);
|
||||
var fd = openFileDescriptor("w");
|
||||
fd.close();
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
}
|
||||
Utils.closeQuietly(os);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -120,18 +111,7 @@ class MediaFile extends UniFile {
|
||||
|
||||
@Override
|
||||
public boolean ensureFile() {
|
||||
if (isFile()) {
|
||||
return true;
|
||||
} else {
|
||||
OutputStream os;
|
||||
try {
|
||||
os = openOutputStream();
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
}
|
||||
Utils.closeQuietly(os);
|
||||
return true;
|
||||
}
|
||||
return isFile();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -169,27 +149,15 @@ class MediaFile extends UniFile {
|
||||
return false;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public OutputStream openOutputStream() throws IOException {
|
||||
return UriOutputStream.create(mContext, mUri, "w");
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public OutputStream openOutputStream(boolean append) throws IOException {
|
||||
return UriOutputStream.create(mContext, mUri, append ? "wa" : "w");
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public InputStream openInputStream() throws IOException {
|
||||
return Contracts.openInputStream(mContext, mUri);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Image.CloseableSource getImageSource() {
|
||||
return Contracts.getImageSource(mContext, mUri);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ParcelFileDescriptor openFileDescriptor(@NonNull String mode) throws IOException {
|
||||
return Contracts.openFileDescriptor(mContext, mUri, mode);
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@ package com.hippo.unifile;
|
||||
|
||||
import android.graphics.ImageDecoder;
|
||||
import android.net.Uri;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.util.Log;
|
||||
import android.webkit.MimeTypeMap;
|
||||
|
||||
@@ -26,10 +27,8 @@ import androidx.annotation.NonNull;
|
||||
import com.hippo.image.Image;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
|
||||
@@ -227,7 +226,7 @@ public class RawFile extends UniFile {
|
||||
results.add(new RawFile(this, file));
|
||||
}
|
||||
}
|
||||
return results.toArray(new UniFile[results.size()]);
|
||||
return results.toArray(new UniFile[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -247,24 +246,6 @@ public class RawFile extends UniFile {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public OutputStream openOutputStream() throws IOException {
|
||||
return new FileOutputStream(mFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public OutputStream openOutputStream(boolean append) throws IOException {
|
||||
return new FileOutputStream(mFile, append);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public InputStream openInputStream() throws IOException {
|
||||
return new FileInputStream(mFile);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Image.CloseableSource getImageSource() {
|
||||
@@ -282,4 +263,15 @@ public class RawFile extends UniFile {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ParcelFileDescriptor openFileDescriptor(@NonNull String mode) throws IOException {
|
||||
var md = ParcelFileDescriptor.parseMode(mode);
|
||||
var pfd = ParcelFileDescriptor.open(mFile, md);
|
||||
if (pfd == null) {
|
||||
throw new IOException("Can't open ParcelFileDescriptor");
|
||||
}
|
||||
return pfd;
|
||||
}
|
||||
}
|
||||
@@ -18,14 +18,13 @@ package com.hippo.unifile;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.hippo.image.Image;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
class SingleDocumentFile extends UniFile {
|
||||
|
||||
@@ -101,18 +100,7 @@ class SingleDocumentFile extends UniFile {
|
||||
|
||||
@Override
|
||||
public boolean ensureFile() {
|
||||
if (isFile()) {
|
||||
return true;
|
||||
} else {
|
||||
OutputStream os;
|
||||
try {
|
||||
os = openOutputStream();
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
}
|
||||
Utils.closeQuietly(os);
|
||||
return true;
|
||||
}
|
||||
return isFile();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -150,27 +138,15 @@ class SingleDocumentFile extends UniFile {
|
||||
return false;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public OutputStream openOutputStream() throws IOException {
|
||||
return Contracts.openOutputStream(mContext, mUri);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public OutputStream openOutputStream(boolean append) throws IOException {
|
||||
return Contracts.openOutputStream(mContext, mUri, append);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public InputStream openInputStream() throws IOException {
|
||||
return Contracts.openInputStream(mContext, mUri);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Image.CloseableSource getImageSource() {
|
||||
return Contracts.getImageSource(mContext, mUri);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ParcelFileDescriptor openFileDescriptor(@NonNull String mode) throws IOException {
|
||||
return Contracts.openFileDescriptor(mContext, mUri, mode);
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@ package com.hippo.unifile;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.webkit.MimeTypeMap;
|
||||
@@ -27,8 +28,6 @@ import androidx.annotation.NonNull;
|
||||
import com.hippo.image.Image;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
|
||||
class TreeDocumentFile extends UniFile {
|
||||
@@ -221,14 +220,13 @@ class TreeDocumentFile extends UniFile {
|
||||
|
||||
final Uri[] result = DocumentsContractApi21.listFiles(mContext, mUri);
|
||||
final ArrayList<UniFile> results = new ArrayList<>();
|
||||
for (int i = 0, n = result.length; i < n; i++) {
|
||||
Uri uri = result[i];
|
||||
for (Uri uri : result) {
|
||||
String name = getFilenameForUri(uri);
|
||||
if (filter.accept(this, name)) {
|
||||
results.add(new TreeDocumentFile(this, mContext, uri, name));
|
||||
}
|
||||
}
|
||||
return results.toArray(new UniFile[results.size()]);
|
||||
return results.toArray(new UniFile[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -249,27 +247,15 @@ class TreeDocumentFile extends UniFile {
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public OutputStream openOutputStream() throws IOException {
|
||||
return Contracts.openOutputStream(mContext, mUri);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public OutputStream openOutputStream(boolean append) throws IOException {
|
||||
return Contracts.openOutputStream(mContext, mUri, append);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public InputStream openInputStream() throws IOException {
|
||||
return Contracts.openInputStream(mContext, mUri);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Image.CloseableSource getImageSource() {
|
||||
return Contracts.getImageSource(mContext, mUri);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ParcelFileDescriptor openFileDescriptor(@NonNull String mode) throws IOException {
|
||||
return Contracts.openFileDescriptor(mContext, mUri, mode);
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
@@ -29,8 +30,6 @@ import com.hippo.image.Image;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -414,35 +413,9 @@ public abstract class UniFile {
|
||||
*/
|
||||
public abstract boolean renameTo(String displayName);
|
||||
|
||||
/**
|
||||
* Open a stream on to the content associated with the file, clean it if it exists
|
||||
*
|
||||
* @return the {@link OutputStream}
|
||||
* @throws IOException
|
||||
*/
|
||||
@NonNull
|
||||
public abstract OutputStream openOutputStream() throws IOException;
|
||||
|
||||
/**
|
||||
* Open a stream on to the content associated with the file
|
||||
*
|
||||
* @param append {@code true} for do not clean it if it exists
|
||||
* @return the {@link OutputStream}
|
||||
* @throws IOException
|
||||
*/
|
||||
@NonNull
|
||||
public abstract OutputStream openOutputStream(boolean append) throws IOException;
|
||||
|
||||
/**
|
||||
* Open a stream on to the content associated with the file
|
||||
*
|
||||
* @return the {@link InputStream}
|
||||
* @throws IOException
|
||||
*/
|
||||
@NonNull
|
||||
public abstract InputStream openInputStream() throws IOException;
|
||||
|
||||
|
||||
@NonNull
|
||||
public abstract Image.CloseableSource getImageSource();
|
||||
|
||||
@NonNull
|
||||
public abstract ParcelFileDescriptor openFileDescriptor(@NonNull String mode) throws IOException;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.hippo.unifile
|
||||
|
||||
import android.os.ParcelFileDescriptor.AutoCloseInputStream
|
||||
import android.os.ParcelFileDescriptor.AutoCloseOutputStream
|
||||
import java.io.FileInputStream
|
||||
import java.io.FileOutputStream
|
||||
|
||||
fun UniFile.openInputStream(): FileInputStream {
|
||||
return AutoCloseInputStream(openFileDescriptor("r"))
|
||||
}
|
||||
|
||||
fun UniFile.openOutputStream(): FileOutputStream {
|
||||
return AutoCloseOutputStream(openFileDescriptor("w"))
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Hippo Seven
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.hippo.unifile;
|
||||
|
||||
/*
|
||||
* Created by Hippo on 8/15/2016.
|
||||
*/
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
// The OutputStream from Context.getContentResolver().openOutputStream()
|
||||
// and FileProvider uri may throw Exception when write. The Exception looks like:
|
||||
// java.io.IOException: write failed: EBADF (Bad file descriptor)
|
||||
// But UriOutputStream can avoid it on my Nexus 5 cm13.
|
||||
// TODO need more test
|
||||
class UriOutputStream extends FileOutputStream {
|
||||
|
||||
private final ParcelFileDescriptor mPfd;
|
||||
|
||||
private UriOutputStream(ParcelFileDescriptor pfd, FileDescriptor fd) {
|
||||
super(fd);
|
||||
mPfd = pfd;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
static OutputStream create(Context context, Uri uri, String mode) throws IOException {
|
||||
ParcelFileDescriptor pfd;
|
||||
try {
|
||||
pfd = context.getContentResolver().openFileDescriptor(uri, mode);
|
||||
} catch (Throwable e) {
|
||||
Utils.throwIfFatal(e);
|
||||
throw new IOException("Can't get ParcelFileDescriptor", e);
|
||||
}
|
||||
if (pfd == null) {
|
||||
throw new IOException("Can't get ParcelFileDescriptor");
|
||||
}
|
||||
FileDescriptor fd = pfd.getFileDescriptor();
|
||||
if (fd == null) {
|
||||
throw new IOException("Can't get FileDescriptor");
|
||||
}
|
||||
|
||||
return new UriOutputStream(pfd, fd);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
mPfd.close();
|
||||
super.close();
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user