You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by er...@apache.org on 2023/10/17 04:04:30 UTC

[cordova-plugin-file] branch master updated: refactor(android): various cleanup (#607)

This is an automated email from the ASF dual-hosted git repository.

erisu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cordova-plugin-file.git


The following commit(s) were added to refs/heads/master by this push:
     new c5bcbdf  refactor(android): various cleanup (#607)
c5bcbdf is described below

commit c5bcbdf766509135ba5fc91a0bfd31b08a06d3b3
Author: エリス <er...@users.noreply.github.com>
AuthorDate: Tue Oct 17 13:04:25 2023 +0900

    refactor(android): various cleanup (#607)
    
    * refactor(android): optimize imports (removed unused & sorted)
    * refactor(android): reindent files and remove trailing spaces
    * refactor(android): remove duplicate Exception catch
    * refactor(android): remove unused global permissions variable
---
 src/android/AssetFilesystem.java    |  27 +-
 src/android/ContentFilesystem.java  | 112 +++---
 src/android/FileUtils.java          | 754 +++++++++++++++++-------------------
 src/android/Filesystem.java         |  48 +--
 src/android/LocalFilesystem.java    | 156 ++++----
 src/android/LocalFilesystemURL.java |  10 +-
 6 files changed, 524 insertions(+), 583 deletions(-)

diff --git a/src/android/AssetFilesystem.java b/src/android/AssetFilesystem.java
index 6d766a4..e2714ee 100644
--- a/src/android/AssetFilesystem.java
+++ b/src/android/AssetFilesystem.java
@@ -24,7 +24,6 @@ import android.net.Uri;
 import org.apache.cordova.CordovaPreferences;
 import org.apache.cordova.CordovaResourceApi;
 import org.apache.cordova.LOG;
-import org.json.JSONArray;
 import org.json.JSONException;
 import org.json.JSONObject;
 
@@ -137,7 +136,7 @@ public class AssetFilesystem extends Filesystem {
     public AssetFilesystem(AssetManager assetManager, CordovaResourceApi resourceApi, CordovaPreferences preferences) {
         super(Uri.parse("file:///android_asset/"), "assets", resourceApi, preferences);
         this.assetManager = assetManager;
-	}
+    }
 
     @Override
     public Uri toNativeUri(LocalFilesystemURL inputURL) {
@@ -204,7 +203,7 @@ public class AssetFilesystem extends Filesystem {
             entries[i] = localUrlforFullPath(new File(inputURL.path, files[i]).getPath());
         }
         return entries;
-	}
+    }
 
     @Override
     public JSONObject getFileForLocalURL(LocalFilesystemURL inputURL,
@@ -241,25 +240,25 @@ public class AssetFilesystem extends Filesystem {
     }
 
     @Override
-	public JSONObject getFileMetadataForLocalURL(LocalFilesystemURL inputURL) throws FileNotFoundException {
+    public JSONObject getFileMetadataForLocalURL(LocalFilesystemURL inputURL) throws FileNotFoundException {
         JSONObject metadata = new JSONObject();
         long size = inputURL.isDirectory ? 0 : getAssetSize(inputURL.path);
         try {
-        	metadata.put("size", size);
-        	metadata.put("type", inputURL.isDirectory ? "text/directory" : resourceApi.getMimeType(toNativeUri(inputURL)));
-        	metadata.put("name", new File(inputURL.path).getName());
-        	metadata.put("fullPath", inputURL.path);
-        	metadata.put("lastModifiedDate", 0);
+            metadata.put("size", size);
+            metadata.put("type", inputURL.isDirectory ? "text/directory" : resourceApi.getMimeType(toNativeUri(inputURL)));
+            metadata.put("name", new File(inputURL.path).getName());
+            metadata.put("fullPath", inputURL.path);
+            metadata.put("lastModifiedDate", 0);
         } catch (JSONException e) {
             return null;
         }
         return metadata;
-	}
+    }
 
-	@Override
-	public boolean canRemoveFileAtLocalURL(LocalFilesystemURL inputURL) {
-		return false;
-	}
+    @Override
+    public boolean canRemoveFileAtLocalURL(LocalFilesystemURL inputURL) {
+        return false;
+    }
 
     @Override
     long writeToFileAtURL(LocalFilesystemURL inputURL, String data, int offset, boolean isBinary) throws NoModificationAllowedException, IOException {
diff --git a/src/android/ContentFilesystem.java b/src/android/ContentFilesystem.java
index d528bd3..b4b0a4e 100644
--- a/src/android/ContentFilesystem.java
+++ b/src/android/ContentFilesystem.java
@@ -38,10 +38,10 @@ public class ContentFilesystem extends Filesystem {
 
     private final Context context;
 
-	public ContentFilesystem(Context context, CordovaResourceApi resourceApi, CordovaPreferences preferences) {
-		super(Uri.parse("content://"), "content", resourceApi, preferences);
+    public ContentFilesystem(Context context, CordovaResourceApi resourceApi, CordovaPreferences preferences) {
+        super(Uri.parse("content://"), "content", resourceApi, preferences);
         this.context = context;
-	}
+    }
 
     @Override
     public Uri toNativeUri(LocalFilesystemURL inputURL) {
@@ -84,41 +84,41 @@ public class ContentFilesystem extends Filesystem {
     }
 
     @Override
-	public JSONObject getFileForLocalURL(LocalFilesystemURL inputURL,
-			String fileName, JSONObject options, boolean directory) throws IOException, TypeMismatchException, JSONException {
+    public JSONObject getFileForLocalURL(LocalFilesystemURL inputURL,
+            String fileName, JSONObject options, boolean directory) throws IOException, TypeMismatchException, JSONException {
         throw new UnsupportedOperationException("getFile() not supported for content:. Use resolveLocalFileSystemURL instead.");
-	}
+    }
 
-	@Override
-	public boolean removeFileAtLocalURL(LocalFilesystemURL inputURL)
-			throws NoModificationAllowedException {
+    @Override
+    public boolean removeFileAtLocalURL(LocalFilesystemURL inputURL)
+            throws NoModificationAllowedException {
         Uri contentUri = toNativeUri(inputURL);
-		try {
+        try {
             context.getContentResolver().delete(contentUri, null, null);
-		} catch (UnsupportedOperationException t) {
-			// Was seeing this on the File mobile-spec tests on 4.0.3 x86 emulator.
-			// The ContentResolver applies only when the file was registered in the
-			// first case, which is generally only the case with images.
+        } catch (UnsupportedOperationException t) {
+            // Was seeing this on the File mobile-spec tests on 4.0.3 x86 emulator.
+            // The ContentResolver applies only when the file was registered in the
+            // first case, which is generally only the case with images.
             NoModificationAllowedException nmae = new NoModificationAllowedException("Deleting not supported for content uri: " + contentUri);
             nmae.initCause(t);
             throw nmae;
-		}
+        }
         return true;
-	}
+    }
 
-	@Override
-	public boolean recursiveRemoveFileAtLocalURL(LocalFilesystemURL inputURL)
-			throws NoModificationAllowedException {
-		throw new NoModificationAllowedException("Cannot remove content url");
-	}
+    @Override
+    public boolean recursiveRemoveFileAtLocalURL(LocalFilesystemURL inputURL)
+            throws NoModificationAllowedException {
+        throw new NoModificationAllowedException("Cannot remove content url");
+    }
 
     @Override
     public LocalFilesystemURL[] listChildren(LocalFilesystemURL inputURL) throws FileNotFoundException {
         throw new UnsupportedOperationException("readEntriesAtLocalURL() not supported for content:. Use resolveLocalFileSystemURL instead.");
     }
 
-	@Override
-	public JSONObject getFileMetadataForLocalURL(LocalFilesystemURL inputURL) throws FileNotFoundException {
+    @Override
+    public JSONObject getFileMetadataForLocalURL(LocalFilesystemURL inputURL) throws FileNotFoundException {
         long size = -1;
         long lastModified = 0;
         Uri nativeUri = toNativeUri(inputURL);
@@ -143,55 +143,55 @@ public class ContentFilesystem extends Filesystem {
             fnfe.initCause(e);
             throw fnfe;
         } finally {
-        	if (cursor != null)
-        		cursor.close();
+            if (cursor != null)
+                cursor.close();
         }
 
         JSONObject metadata = new JSONObject();
         try {
-        	metadata.put("size", size);
-        	metadata.put("type", mimeType);
-        	metadata.put("name", name);
-        	metadata.put("fullPath", inputURL.path);
-        	metadata.put("lastModifiedDate", lastModified);
+            metadata.put("size", size);
+            metadata.put("type", mimeType);
+            metadata.put("name", name);
+            metadata.put("fullPath", inputURL.path);
+            metadata.put("lastModifiedDate", lastModified);
         } catch (JSONException e) {
-        	return null;
+            return null;
         }
         return metadata;
-	}
+    }
 
-	@Override
-	public long writeToFileAtURL(LocalFilesystemURL inputURL, String data,
-			int offset, boolean isBinary) throws NoModificationAllowedException {
+    @Override
+    public long writeToFileAtURL(LocalFilesystemURL inputURL, String data,
+            int offset, boolean isBinary) throws NoModificationAllowedException {
         throw new NoModificationAllowedException("Couldn't write to file given its content URI");
     }
-	@Override
-	public long truncateFileAtURL(LocalFilesystemURL inputURL, long size)
-			throws NoModificationAllowedException {
+    @Override
+    public long truncateFileAtURL(LocalFilesystemURL inputURL, long size)
+            throws NoModificationAllowedException {
         throw new NoModificationAllowedException("Couldn't truncate file given its content URI");
-	}
+    }
 
-	protected Cursor openCursorForURL(Uri nativeUri) {
+    protected Cursor openCursorForURL(Uri nativeUri) {
         ContentResolver contentResolver = context.getContentResolver();
         try {
             return contentResolver.query(nativeUri, null, null, null, null);
         } catch (UnsupportedOperationException e) {
             return null;
         }
-	}
+    }
 
-	private Long resourceSizeForCursor(Cursor cursor) {
+    private Long resourceSizeForCursor(Cursor cursor) {
         int columnIndex = cursor.getColumnIndex(OpenableColumns.SIZE);
         if (columnIndex != -1) {
             String sizeStr = cursor.getString(columnIndex);
             if (sizeStr != null) {
-            	return Long.parseLong(sizeStr);
+                return Long.parseLong(sizeStr);
             }
         }
         return null;
-	}
-	
-	protected Long lastModifiedDateForCursor(Cursor cursor) {
+    }
+
+    protected Long lastModifiedDateForCursor(Cursor cursor) {
         int columnIndex = cursor.getColumnIndex(MediaStore.MediaColumns.DATE_MODIFIED);
         if (columnIndex == -1) {
             columnIndex = cursor.getColumnIndex(DocumentsContract.Document.COLUMN_LAST_MODIFIED);
@@ -203,7 +203,7 @@ public class ContentFilesystem extends Filesystem {
             }
         }
         return null;
-	}
+    }
 
     @Override
     public String filesystemPathForURL(LocalFilesystemURL url) {
@@ -211,14 +211,14 @@ public class ContentFilesystem extends Filesystem {
         return f == null ? null : f.getAbsolutePath();
     }
 
-	@Override
-	public LocalFilesystemURL URLforFilesystemPath(String path) {
-		// Returns null as we don't support reverse mapping back to content:// URLs
-		return null;
-	}
+    @Override
+    public LocalFilesystemURL URLforFilesystemPath(String path) {
+        // Returns null as we don't support reverse mapping back to content:// URLs
+        return null;
+    }
 
-	@Override
-	public boolean canRemoveFileAtLocalURL(LocalFilesystemURL inputURL) {
-		return true;
-	}
+    @Override
+    public boolean canRemoveFileAtLocalURL(LocalFilesystemURL inputURL) {
+        return true;
+    }
 }
diff --git a/src/android/FileUtils.java b/src/android/FileUtils.java
index de973da..d12aa52 100644
--- a/src/android/FileUtils.java
+++ b/src/android/FileUtils.java
@@ -20,7 +20,6 @@ package org.apache.cordova.file;
 
 import android.Manifest;
 import android.app.Activity;
-import android.content.ContentResolver;
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.net.Uri;
@@ -41,22 +40,17 @@ import org.apache.cordova.CordovaWebView;
 import org.apache.cordova.LOG;
 import org.apache.cordova.PermissionHelper;
 import org.apache.cordova.PluginResult;
-
 import org.json.JSONArray;
 import org.json.JSONException;
 import org.json.JSONObject;
 
-import java.io.BufferedInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
-import java.net.HttpURLConnection;
 import java.net.MalformedURLException;
-import java.net.URL;
-import java.security.Permission;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -99,27 +93,6 @@ public class FileUtils extends CordovaPlugin {
 
     private PendingRequests pendingRequests;
 
-    /*
-     * We need both read and write when accessing the storage, I think. (SDK Version < 33)
-     * 
-     * If your app targets Android 13 (SDK 33) or higher and needs to access media files that other apps have created, 
-     * you must request one or more of the following granular media permissions 
-     * instead of the READ_EXTERNAL_STORAGE permission:
-     * 
-     * READ_MEDIA_IMAGES
-     * READ_MEDIA_VIDEO
-     * READ_MEDIA_AUDIO
-     * 
-     * Refer to: https://developer.android.com/about/versions/13/behavior-changes-13
-     */
-
-    private String [] permissions = {
-            Manifest.permission.READ_EXTERNAL_STORAGE,
-            Manifest.permission.WRITE_EXTERNAL_STORAGE,
-            Manifest.permission.READ_MEDIA_IMAGES,
-            Manifest.permission.READ_MEDIA_VIDEO,
-            Manifest.permission.READ_MEDIA_AUDIO};
-
     // This field exists only to support getEntry, below, which has been deprecated
     private static FileUtils filePlugin;
 
@@ -130,18 +103,18 @@ public class FileUtils extends CordovaPlugin {
     private ArrayList<Filesystem> filesystems;
 
     public void registerFilesystem(Filesystem fs) {
-    	if (fs != null && filesystemForName(fs.name)== null) {
-    		this.filesystems.add(fs);
-    	}
+        if (fs != null && filesystemForName(fs.name) == null) {
+            this.filesystems.add(fs);
+        }
     }
 
     private Filesystem filesystemForName(String name) {
-    	for (Filesystem fs:filesystems) {
-    		if (fs != null && fs.name != null && fs.name.equals(name)) {
-    			return fs;
-    		}
-    	}
-    	return null;
+        for (Filesystem fs : filesystems) {
+            if (fs != null && fs.name != null && fs.name.equals(name)) {
+                return fs;
+            }
+        }
+        return null;
     }
 
     protected String[] getExtraFileSystemsPreference(Activity activity) {
@@ -173,21 +146,20 @@ public class FileUtils extends CordovaPlugin {
 
     protected HashMap<String, String> getAvailableFileSystems(Activity activity) {
         Context context = activity.getApplicationContext();
-        HashMap<String, String> availableFileSystems = new HashMap<String,String>();
+        HashMap<String, String> availableFileSystems = new HashMap<String, String>();
 
         availableFileSystems.put("files", context.getFilesDir().getAbsolutePath());
         availableFileSystems.put("documents", new File(context.getFilesDir(), "Documents").getAbsolutePath());
         availableFileSystems.put("cache", context.getCacheDir().getAbsolutePath());
         availableFileSystems.put("root", "/");
         if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
-          try {
-            availableFileSystems.put("files-external", context.getExternalFilesDir(null).getAbsolutePath());
-            availableFileSystems.put("sdcard", Environment.getExternalStorageDirectory().getAbsolutePath());
-            availableFileSystems.put("cache-external", context.getExternalCacheDir().getAbsolutePath());
-          }
-          catch(NullPointerException e) {
-              LOG.d(LOG_TAG, "External storage unavailable, check to see if USB Mass Storage Mode is on");
-          }
+            try {
+                availableFileSystems.put("files-external", context.getExternalFilesDir(null).getAbsolutePath());
+                availableFileSystems.put("sdcard", Environment.getExternalStorageDirectory().getAbsolutePath());
+                availableFileSystems.put("cache-external", context.getExternalCacheDir().getAbsolutePath());
+            } catch (NullPointerException e) {
+                LOG.d(LOG_TAG, "External storage unavailable, check to see if USB Mass Storage Mode is on");
+            }
         }
 
         return availableFileSystems;
@@ -195,75 +167,75 @@ public class FileUtils extends CordovaPlugin {
 
     @Override
     public void initialize(CordovaInterface cordova, CordovaWebView webView) {
-    	super.initialize(cordova, webView);
-    	this.filesystems = new ArrayList<Filesystem>();
+        super.initialize(cordova, webView);
+        this.filesystems = new ArrayList<Filesystem>();
         this.pendingRequests = new PendingRequests();
 
-    	String tempRoot = null;
-    	String persistentRoot = null;
+        String tempRoot = null;
+        String persistentRoot = null;
 
-    	Activity activity = cordova.getActivity();
-    	String packageName = activity.getPackageName();
+        Activity activity = cordova.getActivity();
+        String packageName = activity.getPackageName();
 
         String location = preferences.getString("androidpersistentfilelocation", "internal");
 
-    	tempRoot = activity.getCacheDir().getAbsolutePath();
-    	if ("internal".equalsIgnoreCase(location)) {
-    		persistentRoot = activity.getFilesDir().getAbsolutePath() + "/files/";
-    		this.configured = true;
-    	} else if ("compatibility".equalsIgnoreCase(location)) {
-    		/*
-    		 *  Fall-back to compatibility mode -- this is the logic implemented in
-    		 *  earlier versions of this plugin, and should be maintained here so
-    		 *  that apps which were originally deployed with older versions of the
-    		 *  plugin can continue to provide access to files stored under those
-    		 *  versions.
-    		 */
-    		if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
-    			persistentRoot = Environment.getExternalStorageDirectory().getAbsolutePath();
-    			tempRoot = Environment.getExternalStorageDirectory().getAbsolutePath() +
-    					"/Android/data/" + packageName + "/cache/";
-    		} else {
-    			persistentRoot = "/data/data/" + packageName;
-    		}
-    		this.configured = true;
-    	}
-
-    	if (this.configured) {
-			// Create the directories if they don't exist.
-			File tmpRootFile = new File(tempRoot);
+        tempRoot = activity.getCacheDir().getAbsolutePath();
+        if ("internal".equalsIgnoreCase(location)) {
+            persistentRoot = activity.getFilesDir().getAbsolutePath() + "/files/";
+            this.configured = true;
+        } else if ("compatibility".equalsIgnoreCase(location)) {
+            /*
+             *  Fall-back to compatibility mode -- this is the logic implemented in
+             *  earlier versions of this plugin, and should be maintained here so
+             *  that apps which were originally deployed with older versions of the
+             *  plugin can continue to provide access to files stored under those
+             *  versions.
+             */
+            if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
+                persistentRoot = Environment.getExternalStorageDirectory().getAbsolutePath();
+                tempRoot = Environment.getExternalStorageDirectory().getAbsolutePath() +
+                        "/Android/data/" + packageName + "/cache/";
+            } else {
+                persistentRoot = "/data/data/" + packageName;
+            }
+            this.configured = true;
+        }
+
+        if (this.configured) {
+            // Create the directories if they don't exist.
+            File tmpRootFile = new File(tempRoot);
             File persistentRootFile = new File(persistentRoot);
             tmpRootFile.mkdirs();
             persistentRootFile.mkdirs();
 
-    		// Register initial filesystems
-    		// Note: The temporary and persistent filesystems need to be the first two
-    		// registered, so that they will match window.TEMPORARY and window.PERSISTENT,
-    		// per spec.
-    		this.registerFilesystem(new LocalFilesystem("temporary", webView.getContext(), webView.getResourceApi(), tmpRootFile, preferences));
+            // Register initial filesystems
+            // Note: The temporary and persistent filesystems need to be the first two
+            // registered, so that they will match window.TEMPORARY and window.PERSISTENT,
+            // per spec.
+            this.registerFilesystem(new LocalFilesystem("temporary", webView.getContext(), webView.getResourceApi(), tmpRootFile, preferences));
             this.registerFilesystem(new LocalFilesystem("persistent", webView.getContext(), webView.getResourceApi(), persistentRootFile, preferences));
             this.registerFilesystem(new ContentFilesystem(webView.getContext(), webView.getResourceApi(), preferences));
             this.registerFilesystem(new AssetFilesystem(webView.getContext().getAssets(), webView.getResourceApi(), preferences));
 
             registerExtraFileSystems(getExtraFileSystemsPreference(activity), getAvailableFileSystems(activity));
 
-    		// Initialize static plugin reference for deprecated getEntry method
-    		if (filePlugin == null) {
-    			FileUtils.filePlugin = this;
-    		}
-    	} else {
-    		LOG.e(LOG_TAG, "File plugin configuration error: Please set AndroidPersistentFileLocation in config.xml to one of \"internal\" (for new applications) or \"compatibility\" (for compatibility with previous versions)");
-    		activity.finish();
-    	}
+            // Initialize static plugin reference for deprecated getEntry method
+            if (filePlugin == null) {
+                FileUtils.filePlugin = this;
+            }
+        } else {
+            LOG.e(LOG_TAG, "File plugin configuration error: Please set AndroidPersistentFileLocation in config.xml to one of \"internal\" (for new applications) or \"compatibility\" (for compatibility with previous versions)");
+            activity.finish();
+        }
     }
 
     public static FileUtils getFilePlugin() {
-		return filePlugin;
-	}
+        return filePlugin;
+    }
 
-	private Filesystem filesystemForURL(LocalFilesystemURL localURL) {
-    	if (localURL == null) return null;
-    	return filesystemForName(localURL.fsName);
+    private Filesystem filesystemForURL(LocalFilesystemURL localURL) {
+        if (localURL == null) return null;
+        return filesystemForName(localURL.fsName);
     }
 
     @Override
@@ -274,19 +246,19 @@ public class FileUtils extends CordovaPlugin {
         }
 
         try {
-        	LocalFilesystemURL inputURL = LocalFilesystemURL.parse(uri);
-        	Filesystem fs = this.filesystemForURL(inputURL);
-        	if (fs == null) {
-        		return null;
-        	}
-        	String path = fs.filesystemPathForURL(inputURL);
-
-        	if (path != null) {
-        		return Uri.parse("file://" + fs.filesystemPathForURL(inputURL));
-        	}
-        	return null;
+            LocalFilesystemURL inputURL = LocalFilesystemURL.parse(uri);
+            Filesystem fs = this.filesystemForURL(inputURL);
+            if (fs == null) {
+                return null;
+            }
+            String path = fs.filesystemPathForURL(inputURL);
+
+            if (path != null) {
+                return Uri.parse("file://" + fs.filesystemPathForURL(inputURL));
+            }
+            return null;
         } catch (IllegalArgumentException e) {
-        	return null;
+            return null;
         }
     }
 
@@ -299,14 +271,13 @@ public class FileUtils extends CordovaPlugin {
         if (action.equals("testSaveLocationExists")) {
             threadhelper(new FileOp() {
                 public void run(JSONArray args) {
-                    
+
                     boolean b = DirectoryManager.testSaveLocationExists();
                     callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, b));
                 }
             }, rawArgs, callbackContext);
-        }
-        else if (action.equals("getFreeDiskSpace")) {
-            threadhelper( new FileOp( ){
+        } else if (action.equals("getFreeDiskSpace")) {
+            threadhelper(new FileOp() {
                 public void run(JSONArray args) {
                     // The getFreeDiskSpace plugin API is not documented, but some apps call it anyway via exec().
                     // For compatibility it always returns free space in the primary external storage, and
@@ -315,98 +286,88 @@ public class FileUtils extends CordovaPlugin {
                     callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, l));
                 }
             }, rawArgs, callbackContext);
-        }
-        else if (action.equals("testFileExists")) {
-            threadhelper( new FileOp( ){
+        } else if (action.equals("testFileExists")) {
+            threadhelper(new FileOp() {
                 public void run(JSONArray args) throws JSONException {
-                    String fname=args.getString(0);
+                    String fname = args.getString(0);
                     boolean b = DirectoryManager.testFileExists(fname);
                     callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, b));
                 }
             }, rawArgs, callbackContext);
-        }
-        else if (action.equals("testDirectoryExists")) {
-            threadhelper( new FileOp( ){
+        } else if (action.equals("testDirectoryExists")) {
+            threadhelper(new FileOp() {
                 public void run(JSONArray args) throws JSONException {
-                    String fname=args.getString(0);
+                    String fname = args.getString(0);
                     boolean b = DirectoryManager.testFileExists(fname);
                     callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, b));
                 }
             }, rawArgs, callbackContext);
-        }
-        else if (action.equals("readAsText")) {
-            threadhelper( new FileOp( ){
+        } else if (action.equals("readAsText")) {
+            threadhelper(new FileOp() {
                 public void run(JSONArray args) throws JSONException, MalformedURLException {
                     String encoding = args.getString(1);
                     int start = args.getInt(2);
                     int end = args.getInt(3);
-                    String fname=args.getString(0);
+                    String fname = args.getString(0);
                     readFileAs(fname, start, end, callbackContext, encoding, PluginResult.MESSAGE_TYPE_STRING);
                 }
             }, rawArgs, callbackContext);
-        }
-        else if (action.equals("readAsDataURL")) {
-            threadhelper( new FileOp( ){
-                public void run(JSONArray args) throws JSONException, MalformedURLException  {
+        } else if (action.equals("readAsDataURL")) {
+            threadhelper(new FileOp() {
+                public void run(JSONArray args) throws JSONException, MalformedURLException {
                     int start = args.getInt(1);
                     int end = args.getInt(2);
-                    String fname=args.getString(0);
+                    String fname = args.getString(0);
                     readFileAs(fname, start, end, callbackContext, null, -1);
                 }
             }, rawArgs, callbackContext);
-        }
-        else if (action.equals("readAsArrayBuffer")) {
-            threadhelper( new FileOp( ){
-                public void run(JSONArray args) throws JSONException, MalformedURLException  {
+        } else if (action.equals("readAsArrayBuffer")) {
+            threadhelper(new FileOp() {
+                public void run(JSONArray args) throws JSONException, MalformedURLException {
                     int start = args.getInt(1);
                     int end = args.getInt(2);
-                    String fname=args.getString(0);
+                    String fname = args.getString(0);
                     readFileAs(fname, start, end, callbackContext, null, PluginResult.MESSAGE_TYPE_ARRAYBUFFER);
                 }
             }, rawArgs, callbackContext);
-        }
-        else if (action.equals("readAsBinaryString")) {
-            threadhelper( new FileOp( ){
-                public void run(JSONArray args) throws JSONException, MalformedURLException  {
+        } else if (action.equals("readAsBinaryString")) {
+            threadhelper(new FileOp() {
+                public void run(JSONArray args) throws JSONException, MalformedURLException {
                     int start = args.getInt(1);
                     int end = args.getInt(2);
-                    String fname=args.getString(0);
+                    String fname = args.getString(0);
                     readFileAs(fname, start, end, callbackContext, null, PluginResult.MESSAGE_TYPE_BINARYSTRING);
                 }
             }, rawArgs, callbackContext);
-        }
-        else if (action.equals("write")) {
-            threadhelper( new FileOp( ){
+        } else if (action.equals("write")) {
+            threadhelper(new FileOp() {
                 public void run(JSONArray args) throws JSONException, FileNotFoundException, IOException, NoModificationAllowedException {
-                    String fname=args.getString(0);
+                    String fname = args.getString(0);
                     String nativeURL = resolveLocalFileSystemURI(fname).getString("nativeURL");
-                    String data=args.getString(1);
-                    int offset=args.getInt(2);
-                    Boolean isBinary=args.getBoolean(3);
+                    String data = args.getString(1);
+                    int offset = args.getInt(2);
+                    Boolean isBinary = args.getBoolean(3);
 
-                    if(needPermission(nativeURL, WRITE)) {
+                    if (needPermission(nativeURL, WRITE)) {
                         getWritePermission(rawArgs, ACTION_WRITE, callbackContext);
-                    }
-                    else {
+                    } else {
                         long fileSize = write(fname, data, offset, isBinary);
                         callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, fileSize));
                     }
 
                 }
             }, rawArgs, callbackContext);
-        }
-        else if (action.equals("truncate")) {
-            threadhelper( new FileOp( ){
+        } else if (action.equals("truncate")) {
+            threadhelper(new FileOp() {
                 public void run(JSONArray args) throws JSONException, FileNotFoundException, IOException, NoModificationAllowedException {
-                    String fname=args.getString(0);
-                    int offset=args.getInt(1);
+                    String fname = args.getString(0);
+                    int offset = args.getInt(1);
                     long fileSize = truncateFile(fname, offset);
                     callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, fileSize));
                 }
             }, rawArgs, callbackContext);
-        }
-        else if (action.equals("requestAllFileSystems")) {
-            threadhelper( new FileOp( ){
+        } else if (action.equals("requestAllFileSystems")) {
+            threadhelper(new FileOp() {
                 public void run(JSONArray args) throws IOException, JSONException {
                     callbackContext.success(requestAllFileSystems());
                 }
@@ -415,74 +376,67 @@ public class FileUtils extends CordovaPlugin {
             cordova.getThreadPool().execute(
                     new Runnable() {
                         public void run() {
-                        	try {
-					callbackContext.success(requestAllPaths());
-				} catch (JSONException e) {
-					// TODO Auto-generated catch block
-					e.printStackTrace();
-				}
+                            try {
+                                callbackContext.success(requestAllPaths());
+                            } catch (JSONException e) {
+                                // TODO Auto-generated catch block
+                                e.printStackTrace();
+                            }
                         }
                     }
             );
         } else if (action.equals("requestFileSystem")) {
-            threadhelper( new FileOp( ){
+            threadhelper(new FileOp() {
                 public void run(JSONArray args) throws JSONException {
                     int fstype = args.getInt(0);
                     long requiredSize = args.optLong(1);
                     requestFileSystem(fstype, requiredSize, callbackContext);
                 }
             }, rawArgs, callbackContext);
-        }
-        else if (action.equals("resolveLocalFileSystemURI")) {
-            threadhelper( new FileOp( ){
+        } else if (action.equals("resolveLocalFileSystemURI")) {
+            threadhelper(new FileOp() {
                 public void run(JSONArray args) throws IOException, JSONException {
-                    String fname=args.getString(0);
+                    String fname = args.getString(0);
                     JSONObject obj = resolveLocalFileSystemURI(fname);
                     callbackContext.success(obj);
                 }
             }, rawArgs, callbackContext);
-        }
-        else if (action.equals("getFileMetadata")) {
-            threadhelper( new FileOp( ){
+        } else if (action.equals("getFileMetadata")) {
+            threadhelper(new FileOp() {
                 public void run(JSONArray args) throws FileNotFoundException, JSONException, MalformedURLException {
-                    String fname=args.getString(0);
+                    String fname = args.getString(0);
                     JSONObject obj = getFileMetadata(fname);
                     callbackContext.success(obj);
                 }
             }, rawArgs, callbackContext);
-        }
-        else if (action.equals("getParent")) {
-            threadhelper( new FileOp( ){
+        } else if (action.equals("getParent")) {
+            threadhelper(new FileOp() {
                 public void run(JSONArray args) throws JSONException, IOException {
-                    String fname=args.getString(0);
+                    String fname = args.getString(0);
                     JSONObject obj = getParent(fname);
                     callbackContext.success(obj);
                 }
             }, rawArgs, callbackContext);
-        }
-        else if (action.equals("getDirectory")) {
-            threadhelper( new FileOp( ){
+        } else if (action.equals("getDirectory")) {
+            threadhelper(new FileOp() {
                 public void run(JSONArray args) throws FileExistsException, IOException, TypeMismatchException, EncodingException, JSONException {
                     String dirname = args.getString(0);
                     String path = args.getString(1);
                     String nativeURL = resolveLocalFileSystemURI(dirname).getString("nativeURL");
                     boolean containsCreate = (args.isNull(2)) ? false : args.getJSONObject(2).optBoolean("create", false);
 
-                    if(containsCreate && needPermission(nativeURL, WRITE)) {
+                    if (containsCreate && needPermission(nativeURL, WRITE)) {
                         getWritePermission(rawArgs, ACTION_GET_DIRECTORY, callbackContext);
-                    }
-                    else if(!containsCreate && needPermission(nativeURL, READ)) {
+                    } else if (!containsCreate && needPermission(nativeURL, READ)) {
                         getReadPermission(rawArgs, ACTION_GET_DIRECTORY, callbackContext);
-                    }
-                    else {
+                    } else {
                         JSONObject obj = getFile(dirname, path, args.optJSONObject(2), true);
                         callbackContext.success(obj);
                     }
                 }
             }, rawArgs, callbackContext);
-        }
-        else if (action.equals("getFile")) {
-            threadhelper( new FileOp( ){
+        } else if (action.equals("getFile")) {
+            threadhelper(new FileOp() {
                 public void run(JSONArray args) throws FileExistsException, IOException, TypeMismatchException, EncodingException, JSONException {
                     String dirname = args.getString(0);
                     String path = args.getString(1);
@@ -494,24 +448,21 @@ public class FileUtils extends CordovaPlugin {
                         String nativeURL = resolveLocalFileSystemURI(dirname).getString("nativeURL");
                         boolean containsCreate = (args.isNull(2)) ? false : args.getJSONObject(2).optBoolean("create", false);
 
-                        if(containsCreate && needPermission(nativeURL, WRITE)) {
+                        if (containsCreate && needPermission(nativeURL, WRITE)) {
                             getWritePermission(rawArgs, ACTION_GET_FILE, callbackContext);
-                        }
-                        else if(!containsCreate && needPermission(nativeURL, READ)) {
+                        } else if (!containsCreate && needPermission(nativeURL, READ)) {
                             getReadPermission(rawArgs, ACTION_GET_FILE, callbackContext);
-                        }
-                        else {
+                        } else {
                             JSONObject obj = getFile(dirname, path, args.optJSONObject(2), false);
                             callbackContext.success(obj);
                         }
                     }
                 }
             }, rawArgs, callbackContext);
-        }
-        else if (action.equals("remove")) {
-            threadhelper( new FileOp( ){
+        } else if (action.equals("remove")) {
+            threadhelper(new FileOp() {
                 public void run(JSONArray args) throws JSONException, NoModificationAllowedException, InvalidModificationException, MalformedURLException {
-                    String fname=args.getString(0);
+                    String fname = args.getString(0);
                     boolean success = remove(fname);
                     if (success) {
                         callbackContext.success();
@@ -520,11 +471,10 @@ public class FileUtils extends CordovaPlugin {
                     }
                 }
             }, rawArgs, callbackContext);
-        }
-        else if (action.equals("removeRecursively")) {
-            threadhelper( new FileOp( ){
+        } else if (action.equals("removeRecursively")) {
+            threadhelper(new FileOp() {
                 public void run(JSONArray args) throws JSONException, FileExistsException, MalformedURLException, NoModificationAllowedException {
-                    String fname=args.getString(0);
+                    String fname = args.getString(0);
                     boolean success = removeRecursively(fname);
                     if (success) {
                         callbackContext.success();
@@ -533,56 +483,50 @@ public class FileUtils extends CordovaPlugin {
                     }
                 }
             }, rawArgs, callbackContext);
-        }
-        else if (action.equals("moveTo")) {
-            threadhelper( new FileOp( ){
+        } else if (action.equals("moveTo")) {
+            threadhelper(new FileOp() {
                 public void run(JSONArray args) throws JSONException, NoModificationAllowedException, IOException, InvalidModificationException, EncodingException, FileExistsException {
-                    String fname=args.getString(0);
-                    String newParent=args.getString(1);
-                    String newName=args.getString(2);
+                    String fname = args.getString(0);
+                    String newParent = args.getString(1);
+                    String newName = args.getString(2);
                     JSONObject entry = transferTo(fname, newParent, newName, true);
                     callbackContext.success(entry);
                 }
             }, rawArgs, callbackContext);
-        }
-        else if (action.equals("copyTo")) {
-            threadhelper( new FileOp( ){
+        } else if (action.equals("copyTo")) {
+            threadhelper(new FileOp() {
                 public void run(JSONArray args) throws JSONException, NoModificationAllowedException, IOException, InvalidModificationException, EncodingException, FileExistsException {
-                    String fname=args.getString(0);
-                    String newParent=args.getString(1);
-                    String newName=args.getString(2);
+                    String fname = args.getString(0);
+                    String newParent = args.getString(1);
+                    String newName = args.getString(2);
                     JSONObject entry = transferTo(fname, newParent, newName, false);
                     callbackContext.success(entry);
                 }
             }, rawArgs, callbackContext);
-        }
-        else if (action.equals("readEntries")) {
-            threadhelper( new FileOp( ){
+        } else if (action.equals("readEntries")) {
+            threadhelper(new FileOp() {
                 public void run(JSONArray args) throws FileNotFoundException, JSONException, MalformedURLException, IOException {
                     String directory = args.getString(0);
                     String nativeURL = resolveLocalFileSystemURI(directory).getString("nativeURL");
                     if (needPermission(nativeURL, READ)) {
                         getReadPermission(rawArgs, ACTION_READ_ENTRIES, callbackContext);
-                    }
-                    else {
+                    } else {
                         JSONArray entries = readEntries(directory);
                         callbackContext.success(entries);
                     }
                 }
             }, rawArgs, callbackContext);
-        }
-        else if (action.equals("_getLocalFilesystemPath")) {
+        } else if (action.equals("_getLocalFilesystemPath")) {
             // Internal method for testing: Get the on-disk location of a local filesystem url.
             // [Currently used for testing file-transfer]
-            threadhelper( new FileOp( ){
+            threadhelper(new FileOp() {
                 public void run(JSONArray args) throws FileNotFoundException, JSONException, MalformedURLException {
                     String localURLstr = args.getString(0);
                     String fname = filesystemPathForURL(localURLstr);
                     callbackContext.success(fname);
                 }
             }, rawArgs, callbackContext);
-        }
-        else {
+        } else {
             return false;
         }
         return true;
@@ -591,11 +535,11 @@ public class FileUtils extends CordovaPlugin {
     private void getReadPermission(String rawArgs, int action, CallbackContext callbackContext) {
         int requestCode = pendingRequests.createRequest(rawArgs, action, callbackContext);
         if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
-            PermissionHelper.requestPermissions(this, requestCode, 
-            new String[]{Manifest.permission.READ_MEDIA_IMAGES, Manifest.permission.READ_MEDIA_VIDEO, Manifest.permission.READ_MEDIA_AUDIO});
-          } else {
+            PermissionHelper.requestPermissions(this, requestCode,
+                    new String[]{Manifest.permission.READ_MEDIA_IMAGES, Manifest.permission.READ_MEDIA_VIDEO, Manifest.permission.READ_MEDIA_AUDIO});
+        } else {
             PermissionHelper.requestPermission(this, requestCode, Manifest.permission.READ_EXTERNAL_STORAGE);
-          }
+        }
     }
 
     private void getWritePermission(String rawArgs, int action, CallbackContext callbackContext) {
@@ -603,14 +547,23 @@ public class FileUtils extends CordovaPlugin {
         PermissionHelper.requestPermission(this, requestCode, Manifest.permission.WRITE_EXTERNAL_STORAGE);
     }
 
+    /**
+     * If your app targets Android 13 (SDK 33) or higher and needs to access media files that other apps have created,
+     * you must request one or more of the following granular media permissions READ_MEDIA_*
+     * instead of the READ_EXTERNAL_STORAGE permission:
+     *
+     * Refer to: https://developer.android.com/about/versions/13/behavior-changes-13
+     *
+     * @return
+     */
     private boolean hasReadPermission() {
         if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
-            return PermissionHelper.hasPermission(this, Manifest.permission.READ_MEDIA_IMAGES) 
-            && PermissionHelper.hasPermission(this, Manifest.permission.READ_MEDIA_VIDEO)
-            && PermissionHelper.hasPermission(this, Manifest.permission.READ_MEDIA_AUDIO);
-          } else {
+            return PermissionHelper.hasPermission(this, Manifest.permission.READ_MEDIA_IMAGES)
+                    && PermissionHelper.hasPermission(this, Manifest.permission.READ_MEDIA_VIDEO)
+                    && PermissionHelper.hasPermission(this, Manifest.permission.READ_MEDIA_AUDIO);
+        } else {
             return PermissionHelper.hasPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE);
-          }
+        }
     }
 
     private boolean hasWritePermission() {
@@ -622,20 +575,19 @@ public class FileUtils extends CordovaPlugin {
         ArrayList<String> allowedStorageDirectories = new ArrayList<String>();
         allowedStorageDirectories.add(j.getString("applicationDirectory"));
         allowedStorageDirectories.add(j.getString("applicationStorageDirectory"));
-        if(j.has("externalApplicationStorageDirectory")) {
+        if (j.has("externalApplicationStorageDirectory")) {
             allowedStorageDirectories.add(j.getString("externalApplicationStorageDirectory"));
         }
 
-        if(permissionType == READ && hasReadPermission()) {
+        if (permissionType == READ && hasReadPermission()) {
             return false;
-        }
-        else if(permissionType == WRITE && hasWritePermission()) {
+        } else if (permissionType == WRITE && hasWritePermission()) {
             return false;
         }
 
         // Permission required if the native url lies outside the allowed storage directories
-        for(String directory : allowedStorageDirectories) {
-            if(nativeURL.startsWith(directory)) {
+        for (String directory : allowedStorageDirectories) {
+            if (nativeURL.startsWith(directory)) {
                 return false;
             }
         }
@@ -678,7 +630,7 @@ public class FileUtils extends CordovaPlugin {
         } catch (IllegalArgumentException e) {
             MalformedURLException mue = new MalformedURLException("Unrecognized filesystem URL");
             mue.initCause(e);
-        	throw mue;
+            throw mue;
         }
     }
 
@@ -688,7 +640,7 @@ public class FileUtils extends CordovaPlugin {
 
         // Try all installed filesystems. Return the best matching URL
         // (determined by the shortest resulting URL)
-        for (Filesystem fs: filesystems) {
+        for (Filesystem fs : filesystems) {
             LocalFilesystemURL url = fs.URLforFilesystemPath(localPath);
             if (url != null) {
                 // A shorter fullPath implies that the filesystem is a better
@@ -703,41 +655,39 @@ public class FileUtils extends CordovaPlugin {
     }
 
 
-	/* helper to execute functions async and handle the result codes
+    /* helper to execute functions async and handle the result codes
      *
      */
-    private void threadhelper(final FileOp f, final String rawArgs, final CallbackContext callbackContext){
+    private void threadhelper(final FileOp f, final String rawArgs, final CallbackContext callbackContext) {
         cordova.getThreadPool().execute(new Runnable() {
             public void run() {
                 try {
                     JSONArray args = new JSONArray(rawArgs);
                     f.run(args);
-                } catch ( Exception e) {
-                    if( e instanceof EncodingException){
+                } catch (Exception e) {
+                    if (e instanceof EncodingException) {
                         callbackContext.error(FileUtils.ENCODING_ERR);
-                    } else if(e instanceof FileNotFoundException) {
+                    } else if (e instanceof FileNotFoundException) {
                         callbackContext.error(FileUtils.NOT_FOUND_ERR);
-                    } else if(e instanceof FileExistsException) {
+                    } else if (e instanceof FileExistsException) {
                         callbackContext.error(FileUtils.PATH_EXISTS_ERR);
-                    } else if(e instanceof NoModificationAllowedException ) {
+                    } else if (e instanceof NoModificationAllowedException) {
                         callbackContext.error(FileUtils.NO_MODIFICATION_ALLOWED_ERR);
-                    } else if(e instanceof InvalidModificationException ) {
+                    } else if (e instanceof InvalidModificationException) {
                         callbackContext.error(FileUtils.INVALID_MODIFICATION_ERR);
-                    } else if(e instanceof MalformedURLException ) {
+                    } else if (e instanceof MalformedURLException) {
                         callbackContext.error(FileUtils.ENCODING_ERR);
-                    } else if(e instanceof IOException ) {
+                    } else if (e instanceof IOException) {
                         callbackContext.error(FileUtils.INVALID_MODIFICATION_ERR);
-                    } else if(e instanceof EncodingException ) {
-                        callbackContext.error(FileUtils.ENCODING_ERR);
-                    } else if(e instanceof TypeMismatchException ) {
+                    } else if (e instanceof TypeMismatchException) {
                         callbackContext.error(FileUtils.TYPE_MISMATCH_ERR);
-                    } else if(e instanceof JSONException ) {
+                    } else if (e instanceof JSONException) {
                         callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
                     } else if (e instanceof SecurityException) {
                         callbackContext.error(FileUtils.SECURITY_ERR);
                     } else {
                         e.printStackTrace();
-                    	callbackContext.error(FileUtils.UNKNOWN_ERR);
+                        callbackContext.error(FileUtils.UNKNOWN_ERR);
                     }
                 }
             }
@@ -751,7 +701,7 @@ public class FileUtils extends CordovaPlugin {
      * @return a JSONObject representing a Entry from the filesystem
      * @throws MalformedURLException if the url is not valid
      * @throws FileNotFoundException if the file does not exist
-     * @throws IOException if the user can't read the file
+     * @throws IOException           if the user can't read the file
      * @throws JSONException
      */
     private JSONObject resolveLocalFileSystemURI(String uriString) throws IOException, JSONException {
@@ -785,7 +735,7 @@ public class FileUtils extends CordovaPlugin {
         } catch (IllegalArgumentException e) {
             MalformedURLException mue = new MalformedURLException("Unrecognized filesystem URL");
             mue.initCause(e);
-        	throw mue;
+            throw mue;
         }
         throw new FileNotFoundException();
     }
@@ -800,17 +750,17 @@ public class FileUtils extends CordovaPlugin {
      */
     private JSONArray readEntries(String baseURLstr) throws FileNotFoundException, JSONException, MalformedURLException {
         try {
-        	LocalFilesystemURL inputURL = LocalFilesystemURL.parse(baseURLstr);
-        	Filesystem fs = this.filesystemForURL(inputURL);
-        	if (fs == null) {
-        		throw new MalformedURLException("No installed handlers for this URL");
-        	}
-        	return fs.readEntriesAtLocalURL(inputURL);
+            LocalFilesystemURL inputURL = LocalFilesystemURL.parse(baseURLstr);
+            Filesystem fs = this.filesystemForURL(inputURL);
+            if (fs == null) {
+                throw new MalformedURLException("No installed handlers for this URL");
+            }
+            return fs.readEntriesAtLocalURL(inputURL);
 
         } catch (IllegalArgumentException e) {
             MalformedURLException mue = new MalformedURLException("Unrecognized filesystem URL");
             mue.initCause(e);
-        	throw mue;
+            throw mue;
         }
     }
 
@@ -818,7 +768,7 @@ public class FileUtils extends CordovaPlugin {
      * A setup method that handles the move/copy of files/directories
      *
      * @param newName for the file directory to be called, if null use existing file name
-     * @param move if false do a copy, if true do a move
+     * @param move    if false do a copy, if true do a move
      * @return a Entry object
      * @throws NoModificationAllowedException
      * @throws IOException
@@ -830,7 +780,7 @@ public class FileUtils extends CordovaPlugin {
     private JSONObject transferTo(String srcURLstr, String destURLstr, String newName, boolean move) throws JSONException, NoModificationAllowedException, IOException, InvalidModificationException, EncodingException, FileExistsException {
         if (srcURLstr == null || destURLstr == null) {
             // either no source or no destination provided
-        	throw new FileNotFoundException();
+            throw new FileNotFoundException();
         }
 
         LocalFilesystemURL srcURL = LocalFilesystemURL.parse(srcURLstr);
@@ -860,22 +810,22 @@ public class FileUtils extends CordovaPlugin {
      */
     private boolean removeRecursively(String baseURLstr) throws FileExistsException, NoModificationAllowedException, MalformedURLException {
         try {
-        	LocalFilesystemURL inputURL = LocalFilesystemURL.parse(baseURLstr);
-        	// You can't delete the root directory.
-        	if ("".equals(inputURL.path) || "/".equals(inputURL.path)) {
-        		throw new NoModificationAllowedException("You can't delete the root directory");
-        	}
-
-        	Filesystem fs = this.filesystemForURL(inputURL);
-        	if (fs == null) {
-        		throw new MalformedURLException("No installed handlers for this URL");
-        	}
-        	return fs.recursiveRemoveFileAtLocalURL(inputURL);
+            LocalFilesystemURL inputURL = LocalFilesystemURL.parse(baseURLstr);
+            // You can't delete the root directory.
+            if ("".equals(inputURL.path) || "/".equals(inputURL.path)) {
+                throw new NoModificationAllowedException("You can't delete the root directory");
+            }
+
+            Filesystem fs = this.filesystemForURL(inputURL);
+            if (fs == null) {
+                throw new MalformedURLException("No installed handlers for this URL");
+            }
+            return fs.recursiveRemoveFileAtLocalURL(inputURL);
 
         } catch (IllegalArgumentException e) {
             MalformedURLException mue = new MalformedURLException("Unrecognized filesystem URL");
             mue.initCause(e);
-        	throw mue;
+            throw mue;
         }
     }
 
@@ -891,23 +841,23 @@ public class FileUtils extends CordovaPlugin {
      */
     private boolean remove(String baseURLstr) throws NoModificationAllowedException, InvalidModificationException, MalformedURLException {
         try {
-        	LocalFilesystemURL inputURL = LocalFilesystemURL.parse(baseURLstr);
-        	// You can't delete the root directory.
-        	if ("".equals(inputURL.path) || "/".equals(inputURL.path)) {
+            LocalFilesystemURL inputURL = LocalFilesystemURL.parse(baseURLstr);
+            // You can't delete the root directory.
+            if ("".equals(inputURL.path) || "/".equals(inputURL.path)) {
 
-        		throw new NoModificationAllowedException("You can't delete the root directory");
-        	}
+                throw new NoModificationAllowedException("You can't delete the root directory");
+            }
 
-        	Filesystem fs = this.filesystemForURL(inputURL);
-        	if (fs == null) {
-        		throw new MalformedURLException("No installed handlers for this URL");
-        	}
-        	return fs.removeFileAtLocalURL(inputURL);
+            Filesystem fs = this.filesystemForURL(inputURL);
+            if (fs == null) {
+                throw new MalformedURLException("No installed handlers for this URL");
+            }
+            return fs.removeFileAtLocalURL(inputURL);
 
         } catch (IllegalArgumentException e) {
             MalformedURLException mue = new MalformedURLException("Unrecognized filesystem URL");
             mue.initCause(e);
-        	throw mue;
+            throw mue;
         }
     }
 
@@ -915,9 +865,9 @@ public class FileUtils extends CordovaPlugin {
      * Creates or looks up a file.
      *
      * @param baseURLstr base directory
-     * @param path file/directory to lookup or create
-     * @param options specify whether to create or not
-     * @param directory if true look up directory, if false look up file
+     * @param path       file/directory to lookup or create
+     * @param options    specify whether to create or not
+     * @param directory  if true look up directory, if false look up file
      * @return a Entry object
      * @throws FileExistsException
      * @throws IOException
@@ -927,18 +877,18 @@ public class FileUtils extends CordovaPlugin {
      */
     private JSONObject getFile(String baseURLstr, String path, JSONObject options, boolean directory) throws FileExistsException, IOException, TypeMismatchException, EncodingException, JSONException {
         try {
-        	LocalFilesystemURL inputURL = LocalFilesystemURL.parse(baseURLstr);
+            LocalFilesystemURL inputURL = LocalFilesystemURL.parse(baseURLstr);
 
-        	Filesystem fs = this.filesystemForURL(inputURL);
-        	if (fs == null) {
-        		throw new MalformedURLException("No installed handlers for this URL");
-        	}
-        	return fs.getFileForLocalURL(inputURL, path, options, directory);
+            Filesystem fs = this.filesystemForURL(inputURL);
+            if (fs == null) {
+                throw new MalformedURLException("No installed handlers for this URL");
+            }
+            return fs.getFileForLocalURL(inputURL, path, options, directory);
 
         } catch (IllegalArgumentException e) {
             MalformedURLException mue = new MalformedURLException("Unrecognized filesystem URL");
             mue.initCause(e);
-        	throw mue;
+            throw mue;
         }
 
     }
@@ -949,17 +899,17 @@ public class FileUtils extends CordovaPlugin {
      */
     private JSONObject getParent(String baseURLstr) throws JSONException, IOException {
         try {
-        	LocalFilesystemURL inputURL = LocalFilesystemURL.parse(baseURLstr);
-        	Filesystem fs = this.filesystemForURL(inputURL);
-        	if (fs == null) {
-        		throw new MalformedURLException("No installed handlers for this URL");
-        	}
-        	return fs.getParentForLocalURL(inputURL);
+            LocalFilesystemURL inputURL = LocalFilesystemURL.parse(baseURLstr);
+            Filesystem fs = this.filesystemForURL(inputURL);
+            if (fs == null) {
+                throw new MalformedURLException("No installed handlers for this URL");
+            }
+            return fs.getParentForLocalURL(inputURL);
 
         } catch (IllegalArgumentException e) {
             MalformedURLException mue = new MalformedURLException("Unrecognized filesystem URL");
             mue.initCause(e);
-        	throw mue;
+            throw mue;
         }
     }
 
@@ -970,25 +920,25 @@ public class FileUtils extends CordovaPlugin {
      */
     private JSONObject getFileMetadata(String baseURLstr) throws FileNotFoundException, JSONException, MalformedURLException {
         try {
-        	LocalFilesystemURL inputURL = LocalFilesystemURL.parse(baseURLstr);
-        	Filesystem fs = this.filesystemForURL(inputURL);
-        	if (fs == null) {
-        		throw new MalformedURLException("No installed handlers for this URL");
-        	}
-        	return fs.getFileMetadataForLocalURL(inputURL);
+            LocalFilesystemURL inputURL = LocalFilesystemURL.parse(baseURLstr);
+            Filesystem fs = this.filesystemForURL(inputURL);
+            if (fs == null) {
+                throw new MalformedURLException("No installed handlers for this URL");
+            }
+            return fs.getFileMetadataForLocalURL(inputURL);
 
         } catch (IllegalArgumentException e) {
             MalformedURLException mue = new MalformedURLException("Unrecognized filesystem URL");
             mue.initCause(e);
-        	throw mue;
+            throw mue;
         }
     }
 
     /**
      * Requests a filesystem in which to store application data.
      *
-     * @param type of file system requested
-     * @param requiredSize required free space in the file system in bytes
+     * @param type            of file system requested
+     * @param requiredSize    required free space in the file system in bytes
      * @param callbackContext context for returning the result or error
      * @throws JSONException
      */
@@ -1044,21 +994,20 @@ public class FileUtils extends CordovaPlugin {
         ret.put("dataDirectory", toDirUrl(context.getFilesDir()));
         ret.put("cacheDirectory", toDirUrl(context.getCacheDir()));
         if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
-          try {
-            ret.put("externalApplicationStorageDirectory", toDirUrl(context.getExternalFilesDir(null).getParentFile()));
-            ret.put("externalDataDirectory", toDirUrl(context.getExternalFilesDir(null)));
-            ret.put("externalCacheDirectory", toDirUrl(context.getExternalCacheDir()));
-            ret.put("externalRootDirectory", toDirUrl(Environment.getExternalStorageDirectory()));
-          }
-          catch(NullPointerException e) {
-            /* If external storage is unavailable, context.getExternal* returns null */
-              LOG.d(LOG_TAG, "Unable to access these paths, most liklely due to USB storage");
-          }
+            try {
+                ret.put("externalApplicationStorageDirectory", toDirUrl(context.getExternalFilesDir(null).getParentFile()));
+                ret.put("externalDataDirectory", toDirUrl(context.getExternalFilesDir(null)));
+                ret.put("externalCacheDirectory", toDirUrl(context.getExternalCacheDir()));
+                ret.put("externalRootDirectory", toDirUrl(Environment.getExternalStorageDirectory()));
+            } catch (NullPointerException e) {
+                /* If external storage is unavailable, context.getExternal* returns null */
+                LOG.d(LOG_TAG, "Unable to access these paths, most liklely due to USB storage");
+            }
         }
         return ret;
     }
 
-   /**
+    /**
      * Returns a JSON object representing the given File. Internal APIs should be modified
      * to use URLs instead of raw FS paths wherever possible, when interfacing with this plugin.
      *
@@ -1070,10 +1019,10 @@ public class FileUtils extends CordovaPlugin {
         JSONObject entry;
 
         for (Filesystem fs : filesystems) {
-             entry = fs.makeEntryForFile(file);
-             if (entry != null) {
-                 return entry;
-             }
+            entry = fs.makeEntryForFile(file);
+            if (entry != null) {
+                return entry;
+            }
         }
         return null;
     }
@@ -1090,39 +1039,39 @@ public class FileUtils extends CordovaPlugin {
      */
     @Deprecated
     public static JSONObject getEntry(File file) throws JSONException {
- 		if (getFilePlugin() != null) {
-             return getFilePlugin().getEntryForFile(file);
-		}
-		return null;
+        if (getFilePlugin() != null) {
+            return getFilePlugin().getEntryForFile(file);
+        }
+        return null;
     }
 
     /**
      * Read the contents of a file.
      * This is done in a background thread; the result is sent to the callback.
      *
-     * @param start             Start position in the file.
-     * @param end               End position to stop at (exclusive).
-     * @param callbackContext   The context through which to send the result.
-     * @param encoding          The encoding to return contents as.  Typical value is UTF-8. (see http://www.iana.org/assignments/character-sets)
-     * @param resultType        The desired type of data to send to the callback.
-     * @return                  Contents of file.
+     * @param start           Start position in the file.
+     * @param end             End position to stop at (exclusive).
+     * @param callbackContext The context through which to send the result.
+     * @param encoding        The encoding to return contents as.  Typical value is UTF-8. (see http://www.iana.org/assignments/character-sets)
+     * @param resultType      The desired type of data to send to the callback.
+     * @return Contents of file.
      */
     public void readFileAs(final String srcURLstr, final int start, final int end, final CallbackContext callbackContext, final String encoding, final int resultType) throws MalformedURLException {
         try {
-        	LocalFilesystemURL inputURL = LocalFilesystemURL.parse(srcURLstr);
-        	Filesystem fs = this.filesystemForURL(inputURL);
-        	if (fs == null) {
-        		throw new MalformedURLException("No installed handlers for this URL");
-        	}
+            LocalFilesystemURL inputURL = LocalFilesystemURL.parse(srcURLstr);
+            Filesystem fs = this.filesystemForURL(inputURL);
+            if (fs == null) {
+                throw new MalformedURLException("No installed handlers for this URL");
+            }
 
             fs.readFileAtURL(inputURL, start, end, new Filesystem.ReadFileCallback() {
                 public void handleData(InputStream inputStream, String contentType) {
-            		try {
+                    try {
                         ByteArrayOutputStream os = new ByteArrayOutputStream();
                         final int BUFFER_SIZE = 8192;
                         byte[] buffer = new byte[BUFFER_SIZE];
 
-                        for (;;) {
+                        for (; ; ) {
                             int bytesRead = inputStream.read(buffer, 0, BUFFER_SIZE);
 
                             if (bytesRead <= 0) {
@@ -1131,41 +1080,41 @@ public class FileUtils extends CordovaPlugin {
                             os.write(buffer, 0, bytesRead);
                         }
 
-            			PluginResult result;
-            			switch (resultType) {
-            			case PluginResult.MESSAGE_TYPE_STRING:
-                            result = new PluginResult(PluginResult.Status.OK, os.toString(encoding));
-            				break;
-            			case PluginResult.MESSAGE_TYPE_ARRAYBUFFER:
-                            result = new PluginResult(PluginResult.Status.OK, os.toByteArray());
-            				break;
-            			case PluginResult.MESSAGE_TYPE_BINARYSTRING:
-                            result = new PluginResult(PluginResult.Status.OK, os.toByteArray(), true);
-            				break;
-            			default: // Base64.
-                        byte[] base64 = Base64.encode(os.toByteArray(), Base64.NO_WRAP);
-            			String s = "data:" + contentType + ";base64," + new String(base64, "US-ASCII");
-            			result = new PluginResult(PluginResult.Status.OK, s);
-            			}
-
-            			callbackContext.sendPluginResult(result);
-            		} catch (IOException e) {
-            			LOG.d(LOG_TAG, e.getLocalizedMessage());
-            			callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, NOT_READABLE_ERR));
+                        PluginResult result;
+                        switch (resultType) {
+                            case PluginResult.MESSAGE_TYPE_STRING:
+                                result = new PluginResult(PluginResult.Status.OK, os.toString(encoding));
+                                break;
+                            case PluginResult.MESSAGE_TYPE_ARRAYBUFFER:
+                                result = new PluginResult(PluginResult.Status.OK, os.toByteArray());
+                                break;
+                            case PluginResult.MESSAGE_TYPE_BINARYSTRING:
+                                result = new PluginResult(PluginResult.Status.OK, os.toByteArray(), true);
+                                break;
+                            default: // Base64.
+                                byte[] base64 = Base64.encode(os.toByteArray(), Base64.NO_WRAP);
+                                String s = "data:" + contentType + ";base64," + new String(base64, "US-ASCII");
+                                result = new PluginResult(PluginResult.Status.OK, s);
+                        }
+
+                        callbackContext.sendPluginResult(result);
+                    } catch (IOException e) {
+                        LOG.d(LOG_TAG, e.getLocalizedMessage());
+                        callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, NOT_READABLE_ERR));
                     }
-            	}
+                }
             });
 
 
         } catch (IllegalArgumentException e) {
             MalformedURLException mue = new MalformedURLException("Unrecognized filesystem URL");
             mue.initCause(e);
-        	throw mue;
+            throw mue;
         } catch (FileNotFoundException e) {
-        	callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, NOT_FOUND_ERR));
+            callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, NOT_FOUND_ERR));
         } catch (IOException e) {
-        	LOG.d(LOG_TAG, e.getLocalizedMessage());
-        	callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, NOT_READABLE_ERR));
+            LOG.d(LOG_TAG, e.getLocalizedMessage());
+            callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, NOT_READABLE_ERR));
         }
     }
 
@@ -1173,24 +1122,24 @@ public class FileUtils extends CordovaPlugin {
     /**
      * Write contents of file.
      *
-     * @param data				The contents of the file.
-     * @param offset			The position to begin writing the file.
-     * @param isBinary          True if the file contents are base64-encoded binary data
+     * @param data     The contents of the file.
+     * @param offset   The position to begin writing the file.
+     * @param isBinary True if the file contents are base64-encoded binary data
      */
     /**/
     public long write(String srcURLstr, String data, int offset, boolean isBinary) throws FileNotFoundException, IOException, NoModificationAllowedException {
         try {
-        	LocalFilesystemURL inputURL = LocalFilesystemURL.parse(srcURLstr);
-        	Filesystem fs = this.filesystemForURL(inputURL);
-        	if (fs == null) {
-        		throw new MalformedURLException("No installed handlers for this URL");
-        	}
+            LocalFilesystemURL inputURL = LocalFilesystemURL.parse(srcURLstr);
+            Filesystem fs = this.filesystemForURL(inputURL);
+            if (fs == null) {
+                throw new MalformedURLException("No installed handlers for this URL");
+            }
 
             return fs.writeToFileAtURL(inputURL, data, offset, isBinary);
         } catch (IllegalArgumentException e) {
             MalformedURLException mue = new MalformedURLException("Unrecognized filesystem URL");
             mue.initCause(e);
-        	throw mue;
+            throw mue;
         }
 
     }
@@ -1200,17 +1149,17 @@ public class FileUtils extends CordovaPlugin {
      */
     private long truncateFile(String srcURLstr, long size) throws FileNotFoundException, IOException, NoModificationAllowedException {
         try {
-        	LocalFilesystemURL inputURL = LocalFilesystemURL.parse(srcURLstr);
-        	Filesystem fs = this.filesystemForURL(inputURL);
-        	if (fs == null) {
-        		throw new MalformedURLException("No installed handlers for this URL");
-        	}
+            LocalFilesystemURL inputURL = LocalFilesystemURL.parse(srcURLstr);
+            Filesystem fs = this.filesystemForURL(inputURL);
+            if (fs == null) {
+                throw new MalformedURLException("No installed handlers for this URL");
+            }
 
             return fs.truncateFileAtURL(inputURL, size);
         } catch (IllegalArgumentException e) {
             MalformedURLException mue = new MalformedURLException("Unrecognized filesystem URL");
             mue.initCause(e);
-        	throw mue;
+            throw mue;
         }
     }
 
@@ -1224,18 +1173,15 @@ public class FileUtils extends CordovaPlugin {
 
         final PendingRequests.Request req = pendingRequests.getAndRemove(requestCode);
         if (req != null) {
-            for(int r:grantResults)
-            {
-                if(r == PackageManager.PERMISSION_DENIED)
-                {
+            for (int r : grantResults) {
+                if (r == PackageManager.PERMISSION_DENIED) {
                     req.getCallbackContext().sendPluginResult(new PluginResult(PluginResult.Status.ERROR, SECURITY_ERR));
                     return;
                 }
             }
-            switch(req.getAction())
-            {
+            switch (req.getAction()) {
                 case ACTION_GET_FILE:
-                    threadhelper( new FileOp( ){
+                    threadhelper(new FileOp() {
                         public void run(JSONArray args) throws FileExistsException, IOException, TypeMismatchException, EncodingException, JSONException {
                             String dirname = args.getString(0);
 
@@ -1246,7 +1192,7 @@ public class FileUtils extends CordovaPlugin {
                     }, req.getRawArgs(), req.getCallbackContext());
                     break;
                 case ACTION_GET_DIRECTORY:
-                    threadhelper( new FileOp( ){
+                    threadhelper(new FileOp() {
                         public void run(JSONArray args) throws FileExistsException, IOException, TypeMismatchException, EncodingException, JSONException {
                             String dirname = args.getString(0);
 
@@ -1257,21 +1203,21 @@ public class FileUtils extends CordovaPlugin {
                     }, req.getRawArgs(), req.getCallbackContext());
                     break;
                 case ACTION_WRITE:
-                    threadhelper( new FileOp( ){
+                    threadhelper(new FileOp() {
                         public void run(JSONArray args) throws JSONException, FileNotFoundException, IOException, NoModificationAllowedException {
-                            String fname=args.getString(0);
-                            String data=args.getString(1);
-                            int offset=args.getInt(2);
-                            Boolean isBinary=args.getBoolean(3);
+                            String fname = args.getString(0);
+                            String data = args.getString(1);
+                            int offset = args.getInt(2);
+                            Boolean isBinary = args.getBoolean(3);
                             long fileSize = write(fname, data, offset, isBinary);
                             req.getCallbackContext().sendPluginResult(new PluginResult(PluginResult.Status.OK, fileSize));
                         }
                     }, req.getRawArgs(), req.getCallbackContext());
                     break;
                 case ACTION_READ_ENTRIES:
-                    threadhelper( new FileOp( ){
+                    threadhelper(new FileOp() {
                         public void run(JSONArray args) throws FileNotFoundException, JSONException, MalformedURLException {
-                            String fname=args.getString(0);
+                            String fname = args.getString(0);
                             JSONArray entries = readEntries(fname);
                             req.getCallbackContext().success(entries);
                         }
@@ -1279,13 +1225,13 @@ public class FileUtils extends CordovaPlugin {
                     break;
             }
         } else {
-           LOG.d(LOG_TAG, "Received permission callback for unknown request code");
+            LOG.d(LOG_TAG, "Received permission callback for unknown request code");
         }
     }
 
     private String getMimeType(Uri uri) {
         String fileExtensionFromUrl = MimeTypeMap.getFileExtensionFromUrl(uri.toString()).toLowerCase();
-        return  MimeTypeMap.getSingleton().getMimeTypeFromExtension(fileExtensionFromUrl);
+        return MimeTypeMap.getSingleton().getMimeTypeFromExtension(fileExtensionFromUrl);
     }
 
     public CordovaPluginPathHandler getPathHandler() {
@@ -1340,8 +1286,8 @@ public class FileUtils extends CordovaPlugin {
 
                         try {
                             InputStream fileIS = !isAssetsFS ?
-                                new FileInputStream(file) :
-                                webView.getContext().getAssets().open(fileTarget);
+                                    new FileInputStream(file) :
+                                    webView.getContext().getAssets().open(fileTarget);
 
                             String filePath = !isAssetsFS ? file.toString() : fileTarget;
                             Uri fileUri = Uri.parse(filePath);
diff --git a/src/android/Filesystem.java b/src/android/Filesystem.java
index 5453221..115b3bc 100644
--- a/src/android/Filesystem.java
+++ b/src/android/Filesystem.java
@@ -54,8 +54,8 @@ public abstract class Filesystem {
     }
 
     public interface ReadFileCallback {
-		public void handleData(InputStream inputStream, String contentType) throws IOException;
-	}
+        public void handleData(InputStream inputStream, String contentType) throws IOException;
+    }
 
     public static JSONObject makeEntryForURL(LocalFilesystemURL inputURL, Uri nativeURL) {
         try {
@@ -106,13 +106,13 @@ public abstract class Filesystem {
     }
 
     abstract JSONObject getFileForLocalURL(LocalFilesystemURL inputURL, String path,
-			JSONObject options, boolean directory) throws FileExistsException, IOException, TypeMismatchException, EncodingException, JSONException;
+            JSONObject options, boolean directory) throws FileExistsException, IOException, TypeMismatchException, EncodingException, JSONException;
 
-	abstract boolean removeFileAtLocalURL(LocalFilesystemURL inputURL) throws InvalidModificationException, NoModificationAllowedException;
+    abstract boolean removeFileAtLocalURL(LocalFilesystemURL inputURL) throws InvalidModificationException, NoModificationAllowedException;
 
-	abstract boolean recursiveRemoveFileAtLocalURL(LocalFilesystemURL inputURL) throws FileExistsException, NoModificationAllowedException;
+    abstract boolean recursiveRemoveFileAtLocalURL(LocalFilesystemURL inputURL) throws FileExistsException, NoModificationAllowedException;
 
-	abstract LocalFilesystemURL[] listChildren(LocalFilesystemURL inputURL) throws FileNotFoundException;
+    abstract LocalFilesystemURL[] listChildren(LocalFilesystemURL inputURL) throws FileNotFoundException;
 
     public final JSONArray readEntriesAtLocalURL(LocalFilesystemURL inputURL) throws FileNotFoundException {
         LocalFilesystemURL[] children = listChildren(inputURL);
@@ -125,7 +125,7 @@ public abstract class Filesystem {
         return entries;
     }
 
-	abstract JSONObject getFileMetadataForLocalURL(LocalFilesystemURL inputURL) throws FileNotFoundException;
+    abstract JSONObject getFileMetadataForLocalURL(LocalFilesystemURL inputURL) throws FileNotFoundException;
 
     public Uri getRootUri() {
         return rootUri;
@@ -209,14 +209,14 @@ public abstract class Filesystem {
         return rootEntry;
     }
 
-	public JSONObject getParentForLocalURL(LocalFilesystemURL inputURL) throws IOException {
+    public JSONObject getParentForLocalURL(LocalFilesystemURL inputURL) throws IOException {
         Uri parentUri = inputURL.uri;
         String parentPath = new File(inputURL.uri.getPath()).getParent();
         if (!"/".equals(parentPath)) {
             parentUri = inputURL.uri.buildUpon().path(parentPath + '/').build();
-		}
-		return getEntryForLocalURL(LocalFilesystemURL.parse(parentUri));
-	}
+        }
+        return getEntryForLocalURL(LocalFilesystemURL.parse(parentUri));
+    }
 
     protected LocalFilesystemURL makeDestinationURL(String newName, LocalFilesystemURL srcURL, LocalFilesystemURL destURL, boolean isDirectory) {
         // I know this looks weird but it is to work around a JSON bug.
@@ -236,11 +236,11 @@ public abstract class Filesystem {
         return LocalFilesystemURL.parse(newDest);
     }
 
-	/* Read a source URL (possibly from a different filesystem, srcFs,) and copy it to
-	 * the destination URL on this filesystem, optionally with a new filename.
-	 * If move is true, then this method should either perform an atomic move operation
-	 * or remove the source file when finished.
-	 */
+    /* Read a source URL (possibly from a different filesystem, srcFs,) and copy it to
+     * the destination URL on this filesystem, optionally with a new filename.
+     * If move is true, then this method should either perform an atomic move operation
+     * or remove the source file when finished.
+     */
     public JSONObject copyFileToURL(LocalFilesystemURL destURL, String newName,
             Filesystem srcFs, LocalFilesystemURL srcURL, boolean move) throws IOException, InvalidModificationException, JSONException, NoModificationAllowedException, FileExistsException {
         // First, check to see that we can do it
@@ -293,18 +293,18 @@ public abstract class Filesystem {
         }
     }
 
-	abstract long writeToFileAtURL(LocalFilesystemURL inputURL, String data, int offset,
-			boolean isBinary) throws NoModificationAllowedException, IOException;
+    abstract long writeToFileAtURL(LocalFilesystemURL inputURL, String data, int offset,
+            boolean isBinary) throws NoModificationAllowedException, IOException;
 
-	abstract long truncateFileAtURL(LocalFilesystemURL inputURL, long size)
-			throws IOException, NoModificationAllowedException;
+    abstract long truncateFileAtURL(LocalFilesystemURL inputURL, long size)
+            throws IOException, NoModificationAllowedException;
 
-	// This method should return null if filesystem urls cannot be mapped to paths
-	abstract String filesystemPathForURL(LocalFilesystemURL url);
+    // This method should return null if filesystem urls cannot be mapped to paths
+    abstract String filesystemPathForURL(LocalFilesystemURL url);
 
-	abstract LocalFilesystemURL URLforFilesystemPath(String path);
+    abstract LocalFilesystemURL URLforFilesystemPath(String path);
 
-	abstract boolean canRemoveFileAtLocalURL(LocalFilesystemURL inputURL);
+    abstract boolean canRemoveFileAtLocalURL(LocalFilesystemURL inputURL);
 
     protected class LimitedInputStream extends FilterInputStream {
         long numBytesToRead;
diff --git a/src/android/LocalFilesystem.java b/src/android/LocalFilesystem.java
index 97e4888..6b49f9a 100644
--- a/src/android/LocalFilesystem.java
+++ b/src/android/LocalFilesystem.java
@@ -18,29 +18,25 @@
  */
 package org.apache.cordova.file;
 
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Environment;
+import android.util.Base64;
+
+import org.apache.cordova.CordovaPreferences;
+import org.apache.cordova.CordovaResourceApi;
+import org.json.JSONException;
+import org.json.JSONObject;
+
 import java.io.ByteArrayInputStream;
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
 import java.io.RandomAccessFile;
 import java.nio.channels.FileChannel;
-
-import org.apache.cordova.CordovaPreferences;
-import org.apache.cordova.CordovaResourceApi;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import android.os.Build;
-import android.os.Environment;
-import android.util.Base64;
-import android.net.Uri;
-import android.content.Context;
-import android.content.Intent;
-
 import java.nio.charset.Charset;
 
 public class LocalFilesystem extends Filesystem {
@@ -52,20 +48,20 @@ public class LocalFilesystem extends Filesystem {
     }
 
     public String filesystemPathForFullPath(String fullPath) {
-	    return new File(rootUri.getPath(), fullPath).toString();
-	}
+        return new File(rootUri.getPath(), fullPath).toString();
+    }
 
-	@Override
-	public String filesystemPathForURL(LocalFilesystemURL url) {
-		return filesystemPathForFullPath(url.path);
-	}
+    @Override
+    public String filesystemPathForURL(LocalFilesystemURL url) {
+        return filesystemPathForFullPath(url.path);
+    }
 
-	private String fullPathForFilesystemPath(String absolutePath) {
-		if (absolutePath != null && absolutePath.startsWith(rootUri.getPath())) {
-			return absolutePath.substring(rootUri.getPath().length() - 1);
-		}
-		return null;
-	}
+    private String fullPathForFilesystemPath(String absolutePath) {
+        if (absolutePath != null && absolutePath.startsWith(rootUri.getPath())) {
+            return absolutePath.substring(rootUri.getPath().length() - 1);
+        }
+        return null;
+    }
 
     @Override
     public Uri toNativeUri(LocalFilesystemURL inputURL) {
@@ -103,14 +99,14 @@ public class LocalFilesystem extends Filesystem {
         return LocalFilesystemURL.parse(b.build());
     }
 
-	@Override
-	public LocalFilesystemURL URLforFilesystemPath(String path) {
-	    return localUrlforFullPath(fullPathForFilesystemPath(path));
-	}
+    @Override
+    public LocalFilesystemURL URLforFilesystemPath(String path) {
+        return localUrlforFullPath(fullPathForFilesystemPath(path));
+    }
 
-	@Override
-	public JSONObject getFileForLocalURL(LocalFilesystemURL inputURL,
-			String path, JSONObject options, boolean directory) throws FileExistsException, IOException, TypeMismatchException, EncodingException, JSONException {
+    @Override
+    public JSONObject getFileForLocalURL(LocalFilesystemURL inputURL,
+            String path, JSONObject options, boolean directory) throws FileExistsException, IOException, TypeMismatchException, EncodingException, JSONException {
         boolean create = false;
         boolean exclusive = false;
 
@@ -133,9 +129,9 @@ public class LocalFilesystem extends Filesystem {
             path += "/";
         }
         if (path.startsWith("/")) {
-        	requestedURL = localUrlforFullPath(normalizePath(path));
+            requestedURL = localUrlforFullPath(normalizePath(path));
         } else {
-        	requestedURL = localUrlforFullPath(normalizePath(inputURL.path + "/" + path));
+            requestedURL = localUrlforFullPath(normalizePath(inputURL.path + "/" + path));
         }
 
         File fp = new File(this.filesystemPathForURL(requestedURL));
@@ -170,10 +166,10 @@ public class LocalFilesystem extends Filesystem {
 
         // Return the directory
         return makeEntryForURL(requestedURL);
-	}
+    }
 
-	@Override
-	public boolean removeFileAtLocalURL(LocalFilesystemURL inputURL) throws InvalidModificationException {
+    @Override
+    public boolean removeFileAtLocalURL(LocalFilesystemURL inputURL) throws InvalidModificationException {
 
         File fp = new File(filesystemPathForURL(inputURL));
 
@@ -183,7 +179,7 @@ public class LocalFilesystem extends Filesystem {
         }
 
         return fp.delete();
-	}
+    }
 
     @Override
     public boolean exists(LocalFilesystemURL inputURL) {
@@ -197,12 +193,12 @@ public class LocalFilesystem extends Filesystem {
     }
 
     @Override
-	public boolean recursiveRemoveFileAtLocalURL(LocalFilesystemURL inputURL) throws FileExistsException {
+    public boolean recursiveRemoveFileAtLocalURL(LocalFilesystemURL inputURL) throws FileExistsException {
         File directory = new File(filesystemPathForURL(inputURL));
-    	return removeDirRecursively(directory);
-	}
+        return removeDirRecursively(directory);
+    }
 
-	protected boolean removeDirRecursively(File directory) throws FileExistsException {
+    protected boolean removeDirRecursively(File directory) throws FileExistsException {
         if (directory.isDirectory()) {
             for (File file : directory.listFiles()) {
                 removeDirRecursively(file);
@@ -214,7 +210,7 @@ public class LocalFilesystem extends Filesystem {
         } else {
             return true;
         }
-	}
+    }
 
     @Override
     public LocalFilesystemURL[] listChildren(LocalFilesystemURL inputURL) throws FileNotFoundException {
@@ -236,10 +232,10 @@ public class LocalFilesystem extends Filesystem {
         }
 
         return entries;
-	}
+    }
 
-	@Override
-	public JSONObject getFileMetadataForLocalURL(LocalFilesystemURL inputURL) throws FileNotFoundException {
+    @Override
+    public JSONObject getFileMetadataForLocalURL(LocalFilesystemURL inputURL) throws FileNotFoundException {
         File file = new File(filesystemPathForURL(inputURL));
 
         if (!file.exists()) {
@@ -249,16 +245,16 @@ public class LocalFilesystem extends Filesystem {
         JSONObject metadata = new JSONObject();
         try {
             // Ensure that directories report a size of 0
-        	metadata.put("size", file.isDirectory() ? 0 : file.length());
-        	metadata.put("type", resourceApi.getMimeType(Uri.fromFile(file)));
-        	metadata.put("name", file.getName());
-        	metadata.put("fullPath", inputURL.path);
-        	metadata.put("lastModifiedDate", file.lastModified());
+            metadata.put("size", file.isDirectory() ? 0 : file.length());
+            metadata.put("type", resourceApi.getMimeType(Uri.fromFile(file)));
+            metadata.put("name", file.getName());
+            metadata.put("fullPath", inputURL.path);
+            metadata.put("lastModifiedDate", file.lastModified());
         } catch (JSONException e) {
-        	return null;
+            return null;
         }
         return metadata;
-	}
+    }
 
     private void copyFile(Filesystem srcFs, LocalFilesystemURL srcURL, File destFile, boolean move) throws IOException, InvalidModificationException, NoModificationAllowedException {
         if (move) {
@@ -326,11 +322,11 @@ public class LocalFilesystem extends Filesystem {
         }
     }
 
-	@Override
-	public JSONObject copyFileToURL(LocalFilesystemURL destURL, String newName,
-			Filesystem srcFs, LocalFilesystemURL srcURL, boolean move) throws IOException, InvalidModificationException, JSONException, NoModificationAllowedException, FileExistsException {
+    @Override
+    public JSONObject copyFileToURL(LocalFilesystemURL destURL, String newName,
+            Filesystem srcFs, LocalFilesystemURL srcURL, boolean move) throws IOException, InvalidModificationException, JSONException, NoModificationAllowedException, FileExistsException {
 
-		// Check to see if the destination directory exists
+        // Check to see if the destination directory exists
         String newParent = this.filesystemPathForURL(destURL);
         File destinationDir = new File(newParent);
         if (!destinationDir.exists()) {
@@ -371,11 +367,11 @@ public class LocalFilesystem extends Filesystem {
             copyFile(srcFs, srcURL, destFile, move);
         }
         return makeEntryForURL(destinationURL);
-	}
+    }
 
-	@Override
-	public long writeToFileAtURL(LocalFilesystemURL inputURL, String data,
-			int offset, boolean isBinary) throws IOException, NoModificationAllowedException {
+    @Override
+    public long writeToFileAtURL(LocalFilesystemURL inputURL, String data,
+            int offset, boolean isBinary) throws IOException, NoModificationAllowedException {
 
         boolean append = false;
         if (offset > 0) {
@@ -392,16 +388,16 @@ public class LocalFilesystem extends Filesystem {
         ByteArrayInputStream in = new ByteArrayInputStream(rawData);
         try
         {
-        	byte buff[] = new byte[rawData.length];
+            byte buff[] = new byte[rawData.length];
             String absolutePath = filesystemPathForURL(inputURL);
             FileOutputStream out = new FileOutputStream(absolutePath, append);
             try {
-            	in.read(buff, 0, buff.length);
-            	out.write(buff, 0, rawData.length);
-            	out.flush();
+                in.read(buff, 0, buff.length);
+                out.write(buff, 0, rawData.length);
+                out.flush();
             } finally {
-            	// Always close the output
-            	out.close();
+                // Always close the output
+                out.close();
             }
             if (isPublicDirectory(absolutePath)) {
                 broadcastNewFile(Uri.fromFile(new File(absolutePath)));
@@ -416,7 +412,7 @@ public class LocalFilesystem extends Filesystem {
         }
 
         return rawData.length;
-	}
+    }
 
     private boolean isPublicDirectory(String absolutePath) {
         // TODO: should expose a way to scan app's private files (maybe via a flag).
@@ -441,8 +437,8 @@ public class LocalFilesystem extends Filesystem {
         context.sendBroadcast(intent);
     }
 
-	@Override
-	public long truncateFileAtURL(LocalFilesystemURL inputURL, long size) throws IOException {
+    @Override
+    public long truncateFileAtURL(LocalFilesystemURL inputURL, long size) throws IOException {
         File file = new File(filesystemPathForURL(inputURL));
 
         if (!file.exists()) {
@@ -463,12 +459,12 @@ public class LocalFilesystem extends Filesystem {
         }
 
 
-	}
+    }
 
-	@Override
-	public boolean canRemoveFileAtLocalURL(LocalFilesystemURL inputURL) {
-		String path = filesystemPathForURL(inputURL);
-		File file = new File(path);
-		return file.exists();
-	}
+    @Override
+    public boolean canRemoveFileAtLocalURL(LocalFilesystemURL inputURL) {
+        String path = filesystemPathForURL(inputURL);
+        File file = new File(path);
+        return file.exists();
+    }
 }
diff --git a/src/android/LocalFilesystemURL.java b/src/android/LocalFilesystemURL.java
index d3f41d0..0419679 100644
--- a/src/android/LocalFilesystemURL.java
+++ b/src/android/LocalFilesystemURL.java
@@ -21,8 +21,8 @@ package org.apache.cordova.file;
 import android.net.Uri;
 
 public class LocalFilesystemURL {
-	
-	public static final String FILESYSTEM_PROTOCOL = "cdvfile";
+
+    public static final String FILESYSTEM_PROTOCOL = "cdvfile";
     public static final String CDVFILE_KEYWORD = "__cdvfile_";
 
     public final Uri uri;
@@ -30,12 +30,12 @@ public class LocalFilesystemURL {
     public final String path;
     public final boolean isDirectory;
 
-	private LocalFilesystemURL(Uri uri, String fsName, String fsPath, boolean isDirectory) {
-		this.uri = uri;
+    private LocalFilesystemURL(Uri uri, String fsName, String fsPath, boolean isDirectory) {
+        this.uri = uri;
         this.fsName = fsName;
         this.path = fsPath;
         this.isDirectory = isDirectory;
-	}
+    }
 
     public static LocalFilesystemURL parse(Uri uri) {
         if(!uri.toString().contains(CDVFILE_KEYWORD)) {


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org