下面列出了android.os.ParcelFileDescriptor#AutoCloseOutputStream ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Ensure that any outstanding data for given stream has been committed
* to disk. This is only valid for streams returned from
* {@link #openWrite(String, long, long)}.
*/
public void fsync(@NonNull OutputStream out) throws IOException {
if (ENABLE_REVOCABLE_FD) {
if (out instanceof ParcelFileDescriptor.AutoCloseOutputStream) {
try {
Os.fsync(((ParcelFileDescriptor.AutoCloseOutputStream) out).getFD());
} catch (ErrnoException e) {
throw e.rethrowAsIOException();
}
} else {
throw new IllegalArgumentException("Unrecognized stream");
}
} else {
if (out instanceof FileBridge.FileBridgeOutputStream) {
((FileBridge.FileBridgeOutputStream) out).fsync();
} else {
throw new IllegalArgumentException("Unrecognized stream");
}
}
}
/**
* Gets the output stream for a given Uri.
*
* <p>The returned OutputStream is essentially a {@link java.io.FileOutputStream} which likely
* should be buffered to avoid {@code UnbufferedIoViolation} when running under strict mode.
*
* @param uri The Uri for which the OutputStream is required.
*/
OutputStream getOutputStream(Uri uri) throws FileNotFoundException {
checkNotNull(uri);
ContentProviderClient providerClient = null;
try {
providerClient = makeContentProviderClient(contentResolver, uri);
return new ParcelFileDescriptor.AutoCloseOutputStream(providerClient.openFile(uri, "w"));
} catch (RemoteException re) {
throw new TestStorageException("Unable to access content provider: " + uri, re);
} finally {
if (providerClient != null) {
// Uses #release() to be compatible with API < 24.
providerClient.release();
}
}
}
@Nullable
@Override
public ParcelFileDescriptor openFile(@NonNull Uri uri, @NonNull String mode) throws FileNotFoundException{
if(!"r".equals(mode))
throw new SecurityException("Unexpected file mode "+mode);
if(ApplicationLoader.applicationContext==null)
throw new FileNotFoundException("Unexpected application state");
VoIPBaseService srv=VoIPBaseService.getSharedInstance();
if(srv!=null){
srv.startRingtoneAndVibration();
}
try{
ParcelFileDescriptor[] pipe=ParcelFileDescriptor.createPipe();
ParcelFileDescriptor.AutoCloseOutputStream outputStream = new ParcelFileDescriptor.AutoCloseOutputStream(pipe[1]);
byte[] silentWav={82,73,70,70,41,0,0,0,87,65,86,69,102,109,116,32,16,0,0,0,1,0,1,0,68,(byte)172,0,0,16,(byte)177,2,0,2,0,16,0,100,97,116,97,10,0,0,0,0,0,0,0,0,0,0,0,0,0};
outputStream.write(silentWav);
outputStream.close();
return pipe[0];
}catch(IOException x){
throw new FileNotFoundException(x.getMessage());
}
}
@Nullable
@Override
public ParcelFileDescriptor openFile(@NonNull Uri uri, @NonNull String mode) throws FileNotFoundException{
if(!"r".equals(mode))
throw new SecurityException("Unexpected file mode "+mode);
if(ApplicationLoader.applicationContext==null)
throw new FileNotFoundException("Unexpected application state");
VoIPBaseService srv=VoIPBaseService.getSharedInstance();
if(srv!=null){
srv.startRingtoneAndVibration();
}
try{
ParcelFileDescriptor[] pipe=ParcelFileDescriptor.createPipe();
ParcelFileDescriptor.AutoCloseOutputStream outputStream = new ParcelFileDescriptor.AutoCloseOutputStream(pipe[1]);
byte[] silentWav={82,73,70,70,41,0,0,0,87,65,86,69,102,109,116,32,16,0,0,0,1,0,1,0,68,(byte)172,0,0,16,(byte)177,2,0,2,0,16,0,100,97,116,97,10,0,0,0,0,0,0,0,0,0,0,0,0,0};
outputStream.write(silentWav);
outputStream.close();
return pipe[0];
}catch(IOException x){
throw new FileNotFoundException(x.getMessage());
}
}
@Override
public int synthesizeToFileDescriptor(
IBinder caller,
CharSequence text,
ParcelFileDescriptor fileDescriptor,
Bundle params,
String utteranceId) {
if (!checkNonNull(caller, text, fileDescriptor, params)) {
return TextToSpeech.ERROR;
}
// In test env, ParcelFileDescriptor instance may be EXACTLY the same
// one that is used by client. And it will be closed by a client, thus
// preventing us from writing anything to it.
final ParcelFileDescriptor sameFileDescriptor =
ParcelFileDescriptor.adoptFd(fileDescriptor.detachFd());
SpeechItem item =
new SynthesisToFileOutputStreamSpeechItem(
caller,
Binder.getCallingUid(),
Binder.getCallingPid(),
params,
utteranceId,
text,
new ParcelFileDescriptor.AutoCloseOutputStream(
sameFileDescriptor));
return mSynthHandler.enqueueSpeechItem(TextToSpeech.QUEUE_ADD, item);
}
/**
* Version of {@link #setResource(int)} that allows the caller to specify which
* of the supported wallpaper categories to set.
*
* @param resid The resource ID of the bitmap to be used as the wallpaper image
* @param which Flags indicating which wallpaper(s) to configure with the new imagery
*
* @see #FLAG_LOCK
* @see #FLAG_SYSTEM
*
* @return An integer ID assigned to the newly active wallpaper; or zero on failure.
*
* @throws IOException
*/
@RequiresPermission(android.Manifest.permission.SET_WALLPAPER)
public int setResource(@RawRes int resid, @SetWallpaperFlags int which)
throws IOException {
if (sGlobals.mService == null) {
Log.w(TAG, "WallpaperService not running");
throw new RuntimeException(new DeadSystemException());
}
final Bundle result = new Bundle();
final WallpaperSetCompletion completion = new WallpaperSetCompletion();
try {
Resources resources = mContext.getResources();
/* Set the wallpaper to the default values */
ParcelFileDescriptor fd = sGlobals.mService.setWallpaper(
"res:" + resources.getResourceName(resid),
mContext.getOpPackageName(), null, false, result, which, completion,
mContext.getUserId());
if (fd != null) {
FileOutputStream fos = null;
boolean ok = false;
try {
fos = new ParcelFileDescriptor.AutoCloseOutputStream(fd);
copyStreamToWallpaperFile(resources.openRawResource(resid), fos);
// The 'close()' is the trigger for any server-side image manipulation,
// so we must do that before waiting for completion.
fos.close();
completion.waitForCompletion();
} finally {
// Might be redundant but completion shouldn't wait unless the write
// succeeded; this is a fallback if it threw past the close+wait.
IoUtils.closeQuietly(fos);
}
}
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
return result.getInt(EXTRA_NEW_WALLPAPER_ID, 0);
}
/**
* Like {@link #setBitmap(Bitmap, Rect, boolean, int)}, but allows to pass in an explicit user
* id. If the user id doesn't match the user id the process is running under, calling this
* requires permission {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL}.
* @hide
*/
public int setBitmap(Bitmap fullImage, Rect visibleCropHint,
boolean allowBackup, @SetWallpaperFlags int which, int userId)
throws IOException {
validateRect(visibleCropHint);
if (sGlobals.mService == null) {
Log.w(TAG, "WallpaperService not running");
throw new RuntimeException(new DeadSystemException());
}
final Bundle result = new Bundle();
final WallpaperSetCompletion completion = new WallpaperSetCompletion();
try {
ParcelFileDescriptor fd = sGlobals.mService.setWallpaper(null,
mContext.getOpPackageName(), visibleCropHint, allowBackup,
result, which, completion, userId);
if (fd != null) {
FileOutputStream fos = null;
try {
fos = new ParcelFileDescriptor.AutoCloseOutputStream(fd);
fullImage.compress(Bitmap.CompressFormat.PNG, 90, fos);
fos.close();
completion.waitForCompletion();
} finally {
IoUtils.closeQuietly(fos);
}
}
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
return result.getInt(EXTRA_NEW_WALLPAPER_ID, 0);
}
/**
* Version of {@link #setStream(InputStream, Rect, boolean)} that allows the caller
* to specify which of the supported wallpaper categories to set.
*
* @param bitmapData A stream containing the raw data to install as a wallpaper. This
* data can be in any format handled by {@link BitmapRegionDecoder}.
* @param visibleCropHint The rectangular subregion of the streamed image that should be
* displayed as wallpaper. Passing {@code null} for this parameter means that
* the full image should be displayed if possible given the image's and device's
* aspect ratios, etc.
* @param allowBackup {@code true} if the OS is permitted to back up this wallpaper
* image for restore to a future device; {@code false} otherwise.
* @param which Flags indicating which wallpaper(s) to configure with the new imagery.
* @return An integer ID assigned to the newly active wallpaper; or zero on failure.
*
* @see #getWallpaperId(int)
* @see #FLAG_LOCK
* @see #FLAG_SYSTEM
*
* @throws IOException
*/
@RequiresPermission(android.Manifest.permission.SET_WALLPAPER)
public int setStream(InputStream bitmapData, Rect visibleCropHint,
boolean allowBackup, @SetWallpaperFlags int which)
throws IOException {
validateRect(visibleCropHint);
if (sGlobals.mService == null) {
Log.w(TAG, "WallpaperService not running");
throw new RuntimeException(new DeadSystemException());
}
final Bundle result = new Bundle();
final WallpaperSetCompletion completion = new WallpaperSetCompletion();
try {
ParcelFileDescriptor fd = sGlobals.mService.setWallpaper(null,
mContext.getOpPackageName(), visibleCropHint, allowBackup,
result, which, completion, mContext.getUserId());
if (fd != null) {
FileOutputStream fos = null;
try {
fos = new ParcelFileDescriptor.AutoCloseOutputStream(fd);
copyStreamToWallpaperFile(bitmapData, fos);
fos.close();
completion.waitForCompletion();
} finally {
IoUtils.closeQuietly(fos);
}
}
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
return result.getInt(EXTRA_NEW_WALLPAPER_ID, 0);
}
/**
* Creates a DocumentsArchive instance for opening, browsing and accessing
* documents within the archive passed as a file descriptor.
*
* <p>Note, that this method should be used only if the document does not exist
* on the local storage. A snapshot file will be created, which may be slower
* and consume significant resources, in contrast to using
* {@see createForLocalFile(Context, File, String, char, Uri}.
*
* @param context Context of the provider.
* @param descriptor File descriptor for the archive's contents.
* @param documentId ID of the archive document.
* @param idDelimiter Delimiter for constructing IDs of documents within the archive.
* The delimiter must never be used for IDs of other documents.
* @param Uri notificationUri Uri for notifying that the archive file has changed.
* @see createForLocalFile(Context, File, String, char, Uri)
*/
public static DocumentArchive createForParcelFileDescriptor(
Context context, ParcelFileDescriptor descriptor, String documentId,
char idDelimiter, @Nullable Uri notificationUri)
throws IOException {
File snapshotFile = null;
try {
// Create a copy of the archive, as ZipFile doesn't operate on streams.
// Moreover, ZipInputStream would be inefficient for large files on
// pipes.
snapshotFile = File.createTempFile("android.support.provider.snapshot{",
"}.zip", context.getCacheDir());
try {
final FileOutputStream outputStream =
new ParcelFileDescriptor.AutoCloseOutputStream(
ParcelFileDescriptor.open(
snapshotFile, ParcelFileDescriptor.MODE_WRITE_ONLY));
final ParcelFileDescriptor.AutoCloseInputStream inputStream =
new ParcelFileDescriptor.AutoCloseInputStream(descriptor);
final byte[] buffer = new byte[32 * 1024];
int bytes;
while ((bytes = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytes);
}
outputStream.flush();
return new DocumentArchive(context, snapshotFile, documentId, idDelimiter,
notificationUri);
} catch (Exception e){
CrashReportingManager.logException(e);
return null;
}
} finally {
// On UNIX the file will be still available for processes which opened it, even
// after deleting it. Remove it ASAP, as it won't be used by anyone else.
if (snapshotFile != null) {
snapshotFile.delete();
}
}
}
public static ParcelFileDescriptor pipeFrom(InputStream inputStream)
throws IOException {
final ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe();
final OutputStream output = new ParcelFileDescriptor.AutoCloseOutputStream(pipe[1]);
new TransferThread(inputStream, output).start();
return pipe[0];
}
/**
* Creates a DocumentsArchive instance for opening, browsing and accessing
* documents within the archive passed as a file descriptor.
*
* <p>Note, that this method should be used only if the document does not exist
* on the local storage. A snapshot file will be created, which may be slower
* and consume significant resources, in contrast to using
* {@see createForLocalFile(Context, File, String, char, Uri}.
*
* @param context Context of the provider.
* @param descriptor File descriptor for the archive's contents.
* @param documentId ID of the archive document.
* @param idDelimiter Delimiter for constructing IDs of documents within the archive.
* The delimiter must never be used for IDs of other documents.
* @param Uri notificationUri Uri for notifying that the archive file has changed.
* @see createForLocalFile(Context, File, String, char, Uri)
*/
public static DocumentArchive createForParcelFileDescriptor(
Context context, ParcelFileDescriptor descriptor, String documentId,
char idDelimiter, @Nullable Uri notificationUri)
throws IOException {
File snapshotFile = null;
try {
// Create a copy of the archive, as ZipFile doesn't operate on streams.
// Moreover, ZipInputStream would be inefficient for large files on
// pipes.
snapshotFile = File.createTempFile("android.support.provider.snapshot{",
"}.zip", context.getCacheDir());
try {
final FileOutputStream outputStream =
new ParcelFileDescriptor.AutoCloseOutputStream(
ParcelFileDescriptor.open(
snapshotFile, ParcelFileDescriptor.MODE_WRITE_ONLY));
final ParcelFileDescriptor.AutoCloseInputStream inputStream =
new ParcelFileDescriptor.AutoCloseInputStream(descriptor);
final byte[] buffer = new byte[32 * 1024];
int bytes;
while ((bytes = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytes);
}
outputStream.flush();
return new DocumentArchive(context, snapshotFile, documentId, idDelimiter,
notificationUri);
} catch (Exception e){
Crashlytics.logException(e);
return null;
}
} finally {
// On UNIX the file will be still available for processes which opened it, even
// after deleting it. Remove it ASAP, as it won't be used by anyone else.
if (snapshotFile != null) {
snapshotFile.delete();
}
}
}
public static ParcelFileDescriptor pipeFrom(InputStream inputStream)
throws IOException {
final ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe();
final OutputStream output = new ParcelFileDescriptor.AutoCloseOutputStream(pipe[1]);
new TransferThread(inputStream, output).start();
return pipe[0];
}
/**
* Creates a DocumentsArchive instance for opening, browsing and accessing
* documents within the archive passed as a file descriptor.
*
* <p>Note, that this method should be used only if the document does not exist
* on the local storage. A snapshot file will be created, which may be slower
* and consume significant resources, in contrast to using
* {@see createForLocalFile(Context, File, String, char, Uri}.
*
* @param context Context of the provider.
* @param descriptor File descriptor for the archive's contents.
* @param documentId ID of the archive document.
* @param idDelimiter Delimiter for constructing IDs of documents within the archive.
* The delimiter must never be used for IDs of other documents.
* @param Uri notificationUri Uri for notifying that the archive file has changed.
* @see createForLocalFile(Context, File, String, char, Uri)
*/
public static DocumentArchive createForParcelFileDescriptor(
Context context, ParcelFileDescriptor descriptor, String documentId,
char idDelimiter, @Nullable Uri notificationUri)
throws IOException {
File snapshotFile = null;
try {
// Create a copy of the archive, as ZipFile doesn't operate on streams.
// Moreover, ZipInputStream would be inefficient for large files on
// pipes.
snapshotFile = File.createTempFile("android.support.provider.snapshot{",
"}.zip", context.getCacheDir());
try {
final FileOutputStream outputStream =
new ParcelFileDescriptor.AutoCloseOutputStream(
ParcelFileDescriptor.open(
snapshotFile, ParcelFileDescriptor.MODE_WRITE_ONLY));
final ParcelFileDescriptor.AutoCloseInputStream inputStream =
new ParcelFileDescriptor.AutoCloseInputStream(descriptor);
final byte[] buffer = new byte[32 * 1024];
int bytes;
while ((bytes = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytes);
}
outputStream.flush();
return new DocumentArchive(context, snapshotFile, documentId, idDelimiter,
notificationUri);
} catch (Exception e){
Crashlytics.logException(e);
return null;
}
} finally {
// On UNIX the file will be still available for processes which opened it, even
// after deleting it. Remove it ASAP, as it won't be used by anyone else.
if (snapshotFile != null) {
snapshotFile.delete();
}
}
}
public static ParcelFileDescriptor pipeFrom(InputStream inputStream)
throws IOException {
final ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe();
final OutputStream output = new ParcelFileDescriptor.AutoCloseOutputStream(pipe[1]);
new TransferThread(inputStream, output).start();
return pipe[0];
}
String start() throws InterruptedException {
if (!handlerThread.isAlive()) {
handlerThread.setDaemon(true);
handlerThread.start();
}
Command.Stub commandStub =
new Command.Stub() {
@Override
public void execute(
String command,
List<String> parameters,
@SuppressWarnings("unchecked")
Map shellEnv, // shellEnv comes from aidl and must a Map without type.
boolean executeThroughShell,
ParcelFileDescriptor pdf) {
OutputStream outputReceiver = new ParcelFileDescriptor.AutoCloseOutputStream(pdf);
try {
ShellCommand commandObject =
new ShellCommand(
command, parameters, (Map<String, String>) shellEnv, executeThroughShell);
shellCommandExecutor.execute(commandObject, outputReceiver);
} catch (IOException e) {
Log.w(TAG, "Running command threw an exception", e);
try {
outputReceiver.close();
pdf.close();
} catch (IOException e2) {
Log.w(TAG, "Unable to close the output", e2);
}
}
}
};
PublishResult result =
BlockingPublish.getResult(handlerThread.getLooper(), commandStub.asBinder());
if (result.published) {
String key = result.key;
return key;
} else {
throw new RuntimeException(result.error);
}
}
/**
* Create and return a new auto-close output stream for this asset. This
* will either return a full asset {@link AutoCloseOutputStream}, or
* an underlying {@link ParcelFileDescriptor.AutoCloseOutputStream
* ParcelFileDescriptor.AutoCloseOutputStream} depending on whether the
* the object represents a complete file or sub-section of a file. You
* should only call this once for a particular asset.
*/
public FileOutputStream createOutputStream() throws IOException {
if (mLength < 0) {
return new ParcelFileDescriptor.AutoCloseOutputStream(mFd);
}
return new AutoCloseOutputStream(this);
}
/**
* A simple audio recorder.
*
* @param file The output stream of the recording.
*/
public AudioRecorder(ParcelFileDescriptor file) {
mOutputStream = new ParcelFileDescriptor.AutoCloseOutputStream(file);
}
/**
* A simple audio recorder.
*
* @param file The output stream of the recording.
*/
public AudioRecorder(ParcelFileDescriptor file) {
mOutputStream = new ParcelFileDescriptor.AutoCloseOutputStream(file);
}