/** * Delete a file. May be even on external SD card. * * @param file the file to be deleted. * @return True if successfully deleted. */ public static final boolean deleteFile(@NonNull final File file, Context context) { // First try the normal deletion. boolean fileDelete = deleteFilesInFolder(file, context); if (file.delete() || fileDelete) return true; // Try with Storage Access Framework. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && FileUtil.isOnExtSdCard(file, context)) { DocumentFile document = getDocumentFile(file, false, context); return document.delete(); } // Try the Kitkat workaround. if (Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT) { ContentResolver resolver = context.getContentResolver(); try { Uri uri = MediaStoreUtil.getUriFromFile(file.getAbsolutePath(), context); resolver.delete(uri, null, null); return !file.exists(); } catch (Exception e) { Log.e("AmazeFileUtils", "Error when deleting file " + file.getAbsolutePath(), e); return false; } } return !file.exists(); }
/** * Copy a file. The target file may even be on external SD card for Kitkat. * * @param source The source file * @param target The target file * @return true if the copying was successful. */ @SuppressWarnings("null") public static boolean copyFile(final File source, final File target, Context context) { FileInputStream inStream = null; OutputStream outStream = null; FileChannel inChannel = null; FileChannel outChannel = null; try { inStream = new FileInputStream(source); // First try the normal way if (isWritable(target)) { // standard way outStream = new FileOutputStream(target); inChannel = inStream.getChannel(); outChannel = ((FileOutputStream) outStream).getChannel(); inChannel.transferTo(0, inChannel.size(), outChannel); } else { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { // Storage Access Framework DocumentFile targetDocument = getDocumentFile(target, false, context); outStream = context.getContentResolver().openOutputStream(targetDocument.getUri()); } else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT) { // Workaround for Kitkat ext SD card Uri uri = MediaStoreUtil.getUriFromFile(target.getAbsolutePath(), context); outStream = context.getContentResolver().openOutputStream(uri); } else { return false; } if (outStream != null) { // Both for SAF and for Kitkat, write to output stream. byte[] buffer = new byte[16384]; // MAGIC_NUMBER int bytesRead; while ((bytesRead = inStream.read(buffer)) != -1) { outStream.write(buffer, 0, bytesRead); } } } } catch (Exception e) { Log.e( "AmazeFileUtils", "Error when copying file from " + source.getAbsolutePath() + " to " + target.getAbsolutePath(), e); return false; } finally { try { inStream.close(); } catch (Exception e) { // ignore exception } try { outStream.close(); } catch (Exception e) { // ignore exception } try { inChannel.close(); } catch (Exception e) { // ignore exception } try { outChannel.close(); } catch (Exception e) { // ignore exception } } return true; }