mirror of
https://github.com/apache/cordova-android.git
synced 2025-04-24 10:22:21 +08:00
[CB-2435] Split common methods out of FileUtils into FileHelpers
Also included in this change: - Fixed getMimeType for content:// URIs. - Made getRealPath take a URI string. - Added basic android_asset handling. There is no such thing as a "real path" for a file:///android_asset URI. However, it is possible to get an input stream to one. And even more minor changes: - removed unused FileReader/FileWriter instance variables - added logging when getRealPath fails - fixed indentation issues - removed a try/catch in favor of throwing - removed a null check in favor of throwing - moved getEntry back to FilePlugin
This commit is contained in:
parent
ee38b2ef03
commit
ac2969c3f8
@ -68,13 +68,13 @@ public class AudioHandler extends CordovaPlugin {
|
|||||||
String result = "";
|
String result = "";
|
||||||
|
|
||||||
if (action.equals("startRecordingAudio")) {
|
if (action.equals("startRecordingAudio")) {
|
||||||
this.startRecordingAudio(args.getString(0), FileUtils.stripFileProtocol(args.getString(1)));
|
this.startRecordingAudio(args.getString(0), FileHelper.stripFileProtocol(args.getString(1)));
|
||||||
}
|
}
|
||||||
else if (action.equals("stopRecordingAudio")) {
|
else if (action.equals("stopRecordingAudio")) {
|
||||||
this.stopRecordingAudio(args.getString(0));
|
this.stopRecordingAudio(args.getString(0));
|
||||||
}
|
}
|
||||||
else if (action.equals("startPlayingAudio")) {
|
else if (action.equals("startPlayingAudio")) {
|
||||||
this.startPlayingAudio(args.getString(0), FileUtils.stripFileProtocol(args.getString(1)));
|
this.startPlayingAudio(args.getString(0), FileHelper.stripFileProtocol(args.getString(1)));
|
||||||
}
|
}
|
||||||
else if (action.equals("seekToAudio")) {
|
else if (action.equals("seekToAudio")) {
|
||||||
this.seekToAudio(args.getString(0), args.getInt(1));
|
this.seekToAudio(args.getString(0), args.getInt(1));
|
||||||
@ -102,7 +102,7 @@ public class AudioHandler extends CordovaPlugin {
|
|||||||
}
|
}
|
||||||
else if (action.equals("create")) {
|
else if (action.equals("create")) {
|
||||||
String id = args.getString(0);
|
String id = args.getString(0);
|
||||||
String src = FileUtils.stripFileProtocol(args.getString(1));
|
String src = FileHelper.stripFileProtocol(args.getString(1));
|
||||||
AudioPlayer audio = new AudioPlayer(this, id, src);
|
AudioPlayer audio = new AudioPlayer(this, id, src);
|
||||||
this.players.put(id, audio);
|
this.players.put(id, audio);
|
||||||
}
|
}
|
||||||
|
@ -289,7 +289,7 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
|||||||
|
|
||||||
// If sending base64 image back
|
// If sending base64 image back
|
||||||
if (destType == DATA_URL) {
|
if (destType == DATA_URL) {
|
||||||
bitmap = getScaledBitmap(FileUtils.stripFileProtocol(imageUri.toString()));
|
bitmap = getScaledBitmap(FileHelper.stripFileProtocol(imageUri.toString()));
|
||||||
if (bitmap == null) {
|
if (bitmap == null) {
|
||||||
// Try to get the bitmap from intent.
|
// Try to get the bitmap from intent.
|
||||||
bitmap = (Bitmap)intent.getExtras().get("data");
|
bitmap = (Bitmap)intent.getExtras().get("data");
|
||||||
@ -329,7 +329,7 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
|||||||
|
|
||||||
this.callbackContext.success(uri.toString());
|
this.callbackContext.success(uri.toString());
|
||||||
} else {
|
} else {
|
||||||
bitmap = getScaledBitmap(FileUtils.stripFileProtocol(imageUri.toString()));
|
bitmap = getScaledBitmap(FileHelper.stripFileProtocol(imageUri.toString()));
|
||||||
|
|
||||||
if (rotate != 0 && this.correctOrientation) {
|
if (rotate != 0 && this.correctOrientation) {
|
||||||
bitmap = getRotatedBitmap(rotate, bitmap, exif);
|
bitmap = getRotatedBitmap(rotate, bitmap, exif);
|
||||||
@ -344,7 +344,7 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
|||||||
if (this.encodingType == JPEG) {
|
if (this.encodingType == JPEG) {
|
||||||
String exifPath;
|
String exifPath;
|
||||||
if (this.saveToPhotoAlbum) {
|
if (this.saveToPhotoAlbum) {
|
||||||
exifPath = FileUtils.getRealPathFromURI(uri, this.cordova);
|
exifPath = FileHelper.getRealPath(uri, this.cordova);
|
||||||
} else {
|
} else {
|
||||||
exifPath = uri.getPath();
|
exifPath = uri.getPath();
|
||||||
}
|
}
|
||||||
@ -395,8 +395,8 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
|||||||
this.callbackContext.success(uri.toString());
|
this.callbackContext.success(uri.toString());
|
||||||
} else {
|
} else {
|
||||||
// Get the path to the image. Makes loading so much easier.
|
// Get the path to the image. Makes loading so much easier.
|
||||||
String imagePath = FileUtils.getRealPathFromURI(uri, this.cordova);
|
String imagePath = FileHelper.getRealPath(uri, this.cordova);
|
||||||
String mimeType = FileUtils.getMimeType(imagePath);
|
String mimeType = FileHelper.getMimeType(imagePath, this.cordova);
|
||||||
// Log.d(LOG_TAG, "Real path = " + imagePath);
|
// Log.d(LOG_TAG, "Real path = " + imagePath);
|
||||||
// Log.d(LOG_TAG, "mime type = " + mimeType);
|
// Log.d(LOG_TAG, "mime type = " + mimeType);
|
||||||
// If we don't have a valid image so quit.
|
// If we don't have a valid image so quit.
|
||||||
@ -458,7 +458,7 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
|||||||
|
|
||||||
// Restore exif data to file
|
// Restore exif data to file
|
||||||
if (this.encodingType == JPEG) {
|
if (this.encodingType == JPEG) {
|
||||||
exif.createOutFile(FileUtils.getRealPathFromURI(uri, this.cordova));
|
exif.createOutFile(FileHelper.getRealPath(uri, this.cordova));
|
||||||
exif.writeExifData();
|
exif.writeExifData();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -521,7 +521,7 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
|||||||
*/
|
*/
|
||||||
private void writeUncompressedImage(Uri uri) throws FileNotFoundException,
|
private void writeUncompressedImage(Uri uri) throws FileNotFoundException,
|
||||||
IOException {
|
IOException {
|
||||||
FileInputStream fis = new FileInputStream(FileUtils.stripFileProtocol(imageUri.toString()));
|
FileInputStream fis = new FileInputStream(FileHelper.stripFileProtocol(imageUri.toString()));
|
||||||
OutputStream os = this.cordova.getActivity().getContentResolver().openOutputStream(uri);
|
OutputStream os = this.cordova.getActivity().getContentResolver().openOutputStream(uri);
|
||||||
byte[] buffer = new byte[4096];
|
byte[] buffer = new byte[4096];
|
||||||
int len;
|
int len;
|
||||||
@ -685,7 +685,7 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Clean up initial camera-written image file.
|
// Clean up initial camera-written image file.
|
||||||
(new File(FileUtils.stripFileProtocol(oldImage.toString()))).delete();
|
(new File(FileHelper.stripFileProtocol(oldImage.toString()))).delete();
|
||||||
|
|
||||||
checkForDuplicateImage(imageType);
|
checkForDuplicateImage(imageType);
|
||||||
// Scan for the gallery to update pic refs in gallery
|
// Scan for the gallery to update pic refs in gallery
|
||||||
|
@ -128,7 +128,7 @@ public class Capture extends CordovaPlugin {
|
|||||||
// If the mimeType isn't set the rest will fail
|
// If the mimeType isn't set the rest will fail
|
||||||
// so let's see if we can determine it.
|
// so let's see if we can determine it.
|
||||||
if (mimeType == null || mimeType.equals("") || "null".equals(mimeType)) {
|
if (mimeType == null || mimeType.equals("") || "null".equals(mimeType)) {
|
||||||
mimeType = FileUtils.getMimeType(filePath);
|
mimeType = FileHelper.getMimeType(filePath, cordova);
|
||||||
}
|
}
|
||||||
Log.d(LOG_TAG, "Mime type = " + mimeType);
|
Log.d(LOG_TAG, "Mime type = " + mimeType);
|
||||||
|
|
||||||
@ -155,7 +155,7 @@ public class Capture extends CordovaPlugin {
|
|||||||
private JSONObject getImageData(String filePath, JSONObject obj) throws JSONException {
|
private JSONObject getImageData(String filePath, JSONObject obj) throws JSONException {
|
||||||
BitmapFactory.Options options = new BitmapFactory.Options();
|
BitmapFactory.Options options = new BitmapFactory.Options();
|
||||||
options.inJustDecodeBounds = true;
|
options.inJustDecodeBounds = true;
|
||||||
BitmapFactory.decodeFile(FileUtils.stripFileProtocol(filePath), options);
|
BitmapFactory.decodeFile(FileHelper.stripFileProtocol(filePath), options);
|
||||||
obj.put("height", options.outHeight);
|
obj.put("height", options.outHeight);
|
||||||
obj.put("width", options.outWidth);
|
obj.put("width", options.outWidth);
|
||||||
return obj;
|
return obj;
|
||||||
@ -346,7 +346,7 @@ public class Capture extends CordovaPlugin {
|
|||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
private JSONObject createMediaFile(Uri data) {
|
private JSONObject createMediaFile(Uri data) {
|
||||||
File fp = new File(FileUtils.getRealPathFromURI(data, this.cordova));
|
File fp = new File(FileHelper.getRealPath(data, this.cordova));
|
||||||
JSONObject obj = new JSONObject();
|
JSONObject obj = new JSONObject();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -363,7 +363,7 @@ public class Capture extends CordovaPlugin {
|
|||||||
obj.put("type", VIDEO_3GPP);
|
obj.put("type", VIDEO_3GPP);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
obj.put("type", FileUtils.getMimeType(fp.getAbsolutePath()));
|
obj.put("type", FileHelper.getMimeType(fp.getAbsolutePath(), cordova));
|
||||||
}
|
}
|
||||||
|
|
||||||
obj.put("lastModifiedDate", fp.lastModified());
|
obj.put("lastModifiedDate", fp.lastModified());
|
||||||
|
142
framework/src/org/apache/cordova/FileHelper.java
Normal file
142
framework/src/org/apache/cordova/FileHelper.java
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
/*
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
or more contributor license agreements. See the NOTICE file
|
||||||
|
distributed with this work for additional information
|
||||||
|
regarding copyright ownership. The ASF licenses this file
|
||||||
|
to you under the Apache License, Version 2.0 (the
|
||||||
|
"License"); you may not use this file except in compliance
|
||||||
|
with the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing,
|
||||||
|
software distributed under the License is distributed on an
|
||||||
|
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
KIND, either express or implied. See the License for the
|
||||||
|
specific language governing permissions and limitations
|
||||||
|
under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.cordova;
|
||||||
|
|
||||||
|
import android.database.Cursor;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.webkit.MimeTypeMap;
|
||||||
|
|
||||||
|
import org.apache.cordova.api.CordovaInterface;
|
||||||
|
import org.apache.cordova.api.LOG;
|
||||||
|
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
public class FileHelper {
|
||||||
|
private static final String LOG_TAG = "FileUtils";
|
||||||
|
private static final String _DATA = "_data";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the real path of the given URI string.
|
||||||
|
* If the given URI string represents a content:// URI, the real path is retrieved from the media store.
|
||||||
|
*
|
||||||
|
* @param uriString the URI string of the audio/image/video
|
||||||
|
* @param cordova the current application context
|
||||||
|
* @return the full path to the file
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
public static String getRealPath(String uriString, CordovaInterface cordova) {
|
||||||
|
String realPath = null;
|
||||||
|
|
||||||
|
if (uriString.startsWith("content://")) {
|
||||||
|
String[] proj = { _DATA };
|
||||||
|
Cursor cursor = cordova.getActivity().managedQuery(Uri.parse(uriString), proj, null, null, null);
|
||||||
|
int column_index = cursor.getColumnIndexOrThrow(_DATA);
|
||||||
|
cursor.moveToFirst();
|
||||||
|
realPath = cursor.getString(column_index);
|
||||||
|
if (realPath == null) {
|
||||||
|
LOG.e(LOG_TAG, "Could get real path for URI string %s", uriString);
|
||||||
|
}
|
||||||
|
} else if (uriString.startsWith("file://")) {
|
||||||
|
realPath = uriString.substring(7);
|
||||||
|
if (realPath.startsWith("/android_asset/")) {
|
||||||
|
LOG.e(LOG_TAG, "Cannot get real path for URI string %s because it is a file:///android_asset/ URI.", uriString);
|
||||||
|
realPath = null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
realPath = uriString;
|
||||||
|
}
|
||||||
|
|
||||||
|
return realPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the real path of the given URI.
|
||||||
|
* If the given URI is a content:// URI, the real path is retrieved from the media store.
|
||||||
|
*
|
||||||
|
* @param uri the URI of the audio/image/video
|
||||||
|
* @param cordova the current application context
|
||||||
|
* @return the full path to the file
|
||||||
|
*/
|
||||||
|
public static String getRealPath(Uri uri, CordovaInterface cordova) {
|
||||||
|
return FileHelper.getRealPath(uri.toString(), cordova);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an input stream based on given URI string.
|
||||||
|
*
|
||||||
|
* @param uriString the URI string from which to obtain the input stream
|
||||||
|
* @param cordova the current application context
|
||||||
|
* @return an input stream into the data at the given URI or null if given an invalid URI string
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public static InputStream getInputStreamFromUriString(String uriString, CordovaInterface cordova) throws IOException {
|
||||||
|
if (uriString.startsWith("content")) {
|
||||||
|
Uri uri = Uri.parse(uriString);
|
||||||
|
return cordova.getActivity().getContentResolver().openInputStream(uri);
|
||||||
|
} else if (uriString.startsWith("file:///android_asset/")) {
|
||||||
|
String relativePath = uriString.substring(22);
|
||||||
|
return cordova.getActivity().getAssets().open(relativePath);
|
||||||
|
} else {
|
||||||
|
return new FileInputStream(getRealPath(uriString, cordova));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the "file://" prefix from the given URI string, if applicable.
|
||||||
|
* If the given URI string doesn't have a "file://" prefix, it is returned unchanged.
|
||||||
|
*
|
||||||
|
* @param uriString the URI string to operate on
|
||||||
|
* @return a path without the "file://" prefix
|
||||||
|
*/
|
||||||
|
public static String stripFileProtocol(String uriString) {
|
||||||
|
if (uriString.startsWith("file://")) {
|
||||||
|
uriString = uriString.substring(7);
|
||||||
|
}
|
||||||
|
return uriString;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the mime type of the data specified by the given URI string.
|
||||||
|
*
|
||||||
|
* @param uriString the URI string of the data
|
||||||
|
* @return the mime type of the specified data
|
||||||
|
*/
|
||||||
|
public static String getMimeType(String uriString, CordovaInterface cordova) {
|
||||||
|
String mimeType = null;
|
||||||
|
|
||||||
|
if (uriString.startsWith("content://")) {
|
||||||
|
Uri uri = Uri.parse(uriString);
|
||||||
|
mimeType = cordova.getActivity().getContentResolver().getType(uri);
|
||||||
|
} else {
|
||||||
|
// MimeTypeMap.getFileExtensionFromUrl has a bug that occurs when the filename has a space, so we encode it.
|
||||||
|
// We also convert the URI string to lower case to ensure compatibility with MimeTypeMap (see CB-2185).
|
||||||
|
String encodedUriString = uriString.replace(" ", "%20").toLowerCase();
|
||||||
|
String extension = MimeTypeMap.getFileExtensionFromUrl(encodedUriString);
|
||||||
|
if (extension.equals("3ga")) {
|
||||||
|
mimeType = "audio/3gpp";
|
||||||
|
} else {
|
||||||
|
mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mimeType;
|
||||||
|
}
|
||||||
|
}
|
@ -750,8 +750,7 @@ public class FileTransfer extends CordovaPlugin {
|
|||||||
Log.d(LOG_TAG, "Saved file: " + target);
|
Log.d(LOG_TAG, "Saved file: " + target);
|
||||||
|
|
||||||
// create FileEntry object
|
// create FileEntry object
|
||||||
FileUtils fileUtil = new FileUtils();
|
JSONObject fileEntry = FileUtils.getEntry(file);
|
||||||
JSONObject fileEntry = fileUtil.getEntry(file);
|
|
||||||
|
|
||||||
result = new PluginResult(PluginResult.Status.OK, fileEntry);
|
result = new PluginResult(PluginResult.Status.OK, fileEntry);
|
||||||
} catch (FileNotFoundException e) {
|
} catch (FileNotFoundException e) {
|
||||||
|
@ -15,18 +15,16 @@
|
|||||||
KIND, either express or implied. See the License for the
|
KIND, either express or implied. See the License for the
|
||||||
specific language governing permissions and limitations
|
specific language governing permissions and limitations
|
||||||
under the License.
|
under the License.
|
||||||
*/
|
*/
|
||||||
package org.apache.cordova;
|
package org.apache.cordova;
|
||||||
|
|
||||||
import java.io.*;
|
import android.database.Cursor;
|
||||||
import java.net.MalformedURLException;
|
import android.net.Uri;
|
||||||
import java.net.URL;
|
import android.os.Environment;
|
||||||
import java.net.URLDecoder;
|
import android.provider.MediaStore;
|
||||||
import java.nio.channels.FileChannel;
|
|
||||||
|
|
||||||
import org.apache.commons.codec.binary.Base64;
|
import org.apache.commons.codec.binary.Base64;
|
||||||
import org.apache.cordova.api.CallbackContext;
|
import org.apache.cordova.api.CallbackContext;
|
||||||
import org.apache.cordova.api.CordovaInterface;
|
|
||||||
import org.apache.cordova.api.CordovaPlugin;
|
import org.apache.cordova.api.CordovaPlugin;
|
||||||
import org.apache.cordova.api.PluginResult;
|
import org.apache.cordova.api.PluginResult;
|
||||||
import org.apache.cordova.file.EncodingException;
|
import org.apache.cordova.file.EncodingException;
|
||||||
@ -38,12 +36,20 @@ import org.json.JSONArray;
|
|||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.RandomAccessFile;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import java.nio.channels.FileChannel;
|
||||||
//import android.content.Context;
|
//import android.content.Context;
|
||||||
import android.database.Cursor;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Environment;
|
|
||||||
import android.provider.MediaStore;
|
|
||||||
import android.webkit.MimeTypeMap;
|
|
||||||
|
|
||||||
//import android.app.Activity;
|
//import android.app.Activity;
|
||||||
|
|
||||||
@ -53,8 +59,7 @@ import android.webkit.MimeTypeMap;
|
|||||||
*/
|
*/
|
||||||
public class FileUtils extends CordovaPlugin {
|
public class FileUtils extends CordovaPlugin {
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
private static final String LOG_TAG = "FileUtils";
|
private static final String LOG_TAG = "FilePlugin";
|
||||||
private static final String _DATA = "_data"; // The column name where the file path is stored
|
|
||||||
|
|
||||||
public static int NOT_FOUND_ERR = 1;
|
public static int NOT_FOUND_ERR = 1;
|
||||||
public static int SECURITY_ERR = 2;
|
public static int SECURITY_ERR = 2;
|
||||||
@ -75,9 +80,6 @@ public class FileUtils extends CordovaPlugin {
|
|||||||
public static int RESOURCE = 2;
|
public static int RESOURCE = 2;
|
||||||
public static int APPLICATION = 3;
|
public static int APPLICATION = 3;
|
||||||
|
|
||||||
FileReader f_in;
|
|
||||||
FileWriter f_out;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*/
|
*/
|
||||||
@ -250,11 +252,11 @@ public class FileUtils extends CordovaPlugin {
|
|||||||
* @param filePath the path to check
|
* @param filePath the path to check
|
||||||
*/
|
*/
|
||||||
private void notifyDelete(String filePath) {
|
private void notifyDelete(String filePath) {
|
||||||
String newFilePath = getRealPathFromURI(Uri.parse(filePath), cordova);
|
String newFilePath = FileHelper.getRealPath(filePath, cordova);
|
||||||
try {
|
try {
|
||||||
this.cordova.getActivity().getContentResolver().delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
|
this.cordova.getActivity().getContentResolver().delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
|
||||||
MediaStore.Images.Media.DATA + " = ?",
|
MediaStore.Images.Media.DATA + " = ?",
|
||||||
new String[] { newFilePath });
|
new String[] { newFilePath });
|
||||||
} catch (UnsupportedOperationException t) {
|
} catch (UnsupportedOperationException t) {
|
||||||
// Was seeing this on the File mobile-spec tests on 4.0.3 x86 emulator.
|
// 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
|
// The ContentResolver applies only when the file was registered in the
|
||||||
@ -357,8 +359,8 @@ public class FileUtils extends CordovaPlugin {
|
|||||||
* @throws FileExistsException
|
* @throws FileExistsException
|
||||||
*/
|
*/
|
||||||
private JSONObject transferTo(String fileName, String newParent, String newName, boolean move) throws JSONException, NoModificationAllowedException, IOException, InvalidModificationException, EncodingException, FileExistsException {
|
private JSONObject transferTo(String fileName, String newParent, String newName, boolean move) throws JSONException, NoModificationAllowedException, IOException, InvalidModificationException, EncodingException, FileExistsException {
|
||||||
String newFileName = getRealPathFromURI(Uri.parse(fileName), cordova);
|
String newFileName = FileHelper.getRealPath(fileName, cordova);
|
||||||
newParent = getRealPathFromURI(Uri.parse(newParent), cordova);
|
newParent = FileHelper.getRealPath(newParent, cordova);
|
||||||
|
|
||||||
// Check for invalid file name
|
// Check for invalid file name
|
||||||
if (newName != null && newName.contains(":")) {
|
if (newName != null && newName.contains(":")) {
|
||||||
@ -397,14 +399,14 @@ public class FileUtils extends CordovaPlugin {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (move) {
|
if (move) {
|
||||||
JSONObject newFileEntry = moveFile(source, destination);
|
JSONObject newFileEntry = moveFile(source, destination);
|
||||||
|
|
||||||
// If we've moved a file given its content URI, we need to clean up.
|
// If we've moved a file given its content URI, we need to clean up.
|
||||||
if (fileName.startsWith("content://")) {
|
if (fileName.startsWith("content://")) {
|
||||||
notifyDelete(fileName);
|
notifyDelete(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
return newFileEntry;
|
return newFileEntry;
|
||||||
} else {
|
} else {
|
||||||
return copyFile(source, destination);
|
return copyFile(source, destination);
|
||||||
}
|
}
|
||||||
@ -761,7 +763,7 @@ public class FileUtils extends CordovaPlugin {
|
|||||||
if (fileName.startsWith("/")) {
|
if (fileName.startsWith("/")) {
|
||||||
fp = new File(fileName);
|
fp = new File(fileName);
|
||||||
} else {
|
} else {
|
||||||
dirPath = getRealPathFromURI(Uri.parse(dirPath), cordova);
|
dirPath = FileHelper.getRealPath(dirPath, cordova);
|
||||||
fp = new File(dirPath + File.separator + fileName);
|
fp = new File(dirPath + File.separator + fileName);
|
||||||
}
|
}
|
||||||
return fp;
|
return fp;
|
||||||
@ -776,7 +778,7 @@ public class FileUtils extends CordovaPlugin {
|
|||||||
* @throws JSONException
|
* @throws JSONException
|
||||||
*/
|
*/
|
||||||
private JSONObject getParent(String filePath) throws JSONException {
|
private JSONObject getParent(String filePath) throws JSONException {
|
||||||
filePath = getRealPathFromURI(Uri.parse(filePath), cordova);
|
filePath = FileHelper.getRealPath(filePath, cordova);
|
||||||
|
|
||||||
if (atRootDirectory(filePath)) {
|
if (atRootDirectory(filePath)) {
|
||||||
return getEntry(filePath);
|
return getEntry(filePath);
|
||||||
@ -792,7 +794,7 @@ public class FileUtils extends CordovaPlugin {
|
|||||||
* @return true if we are at the root, false otherwise.
|
* @return true if we are at the root, false otherwise.
|
||||||
*/
|
*/
|
||||||
private boolean atRootDirectory(String filePath) {
|
private boolean atRootDirectory(String filePath) {
|
||||||
filePath = getRealPathFromURI(Uri.parse(filePath), cordova);
|
filePath = FileHelper.getRealPath(filePath, cordova);
|
||||||
|
|
||||||
if (filePath.equals(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Android/data/" + cordova.getActivity().getPackageName() + "/cache") ||
|
if (filePath.equals(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Android/data/" + cordova.getActivity().getPackageName() + "/cache") ||
|
||||||
filePath.equals(Environment.getExternalStorageDirectory().getAbsolutePath()) ||
|
filePath.equals(Environment.getExternalStorageDirectory().getAbsolutePath()) ||
|
||||||
@ -802,19 +804,6 @@ public class FileUtils extends CordovaPlugin {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* This method removes the "file://" from the passed in filePath
|
|
||||||
*
|
|
||||||
* @param filePath to be checked.
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static String stripFileProtocol(String filePath) {
|
|
||||||
if (filePath.startsWith("file://")) {
|
|
||||||
filePath = filePath.substring(7);
|
|
||||||
}
|
|
||||||
return filePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a File object from the passed in path
|
* Create a File object from the passed in path
|
||||||
*
|
*
|
||||||
@ -822,7 +811,7 @@ public class FileUtils extends CordovaPlugin {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private File createFileObject(String filePath) {
|
private File createFileObject(String filePath) {
|
||||||
filePath = getRealPathFromURI(Uri.parse(filePath), cordova);
|
filePath = FileHelper.getRealPath(filePath, cordova);
|
||||||
|
|
||||||
File file = new File(filePath);
|
File file = new File(filePath);
|
||||||
return file;
|
return file;
|
||||||
@ -862,7 +851,7 @@ public class FileUtils extends CordovaPlugin {
|
|||||||
|
|
||||||
JSONObject metadata = new JSONObject();
|
JSONObject metadata = new JSONObject();
|
||||||
metadata.put("size", file.length());
|
metadata.put("size", file.length());
|
||||||
metadata.put("type", getMimeType(filePath));
|
metadata.put("type", FileHelper.getMimeType(filePath, cordova));
|
||||||
metadata.put("name", file.getName());
|
metadata.put("name", file.getName());
|
||||||
metadata.put("fullPath", filePath);
|
metadata.put("fullPath", filePath);
|
||||||
metadata.put("lastModifiedDate", file.lastModified());
|
metadata.put("lastModifiedDate", file.lastModified());
|
||||||
@ -913,21 +902,21 @@ public class FileUtils extends CordovaPlugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a JSON Object representing a directory on the device's file system
|
* Returns a JSON object representing the given File.
|
||||||
*
|
*
|
||||||
* @param path to the directory
|
* @param file the File to convert
|
||||||
* @return
|
* @return a JSON representation of the given File
|
||||||
* @throws JSONException
|
* @throws JSONException
|
||||||
*/
|
*/
|
||||||
public JSONObject getEntry(File file) throws JSONException {
|
public static JSONObject getEntry(File file) throws JSONException {
|
||||||
JSONObject entry = new JSONObject();
|
JSONObject entry = new JSONObject();
|
||||||
|
|
||||||
entry.put("isFile", file.isFile());
|
entry.put("isFile", file.isFile());
|
||||||
entry.put("isDirectory", file.isDirectory());
|
entry.put("isDirectory", file.isDirectory());
|
||||||
entry.put("name", file.getName());
|
entry.put("name", file.getName());
|
||||||
entry.put("fullPath", "file://" + file.getAbsolutePath());
|
entry.put("fullPath", "file://" + file.getAbsolutePath());
|
||||||
// I can't add the next thing it as it would be an infinite loop
|
// The file system can't be specified, as it would lead to an infinite loop.
|
||||||
//entry.put("filesystem", null);
|
// entry.put("filesystem", null);
|
||||||
|
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
@ -983,7 +972,7 @@ public class FileUtils extends CordovaPlugin {
|
|||||||
public String readAsText(String filename, String encoding, int start, int end) throws FileNotFoundException, IOException {
|
public String readAsText(String filename, String encoding, int start, int end) throws FileNotFoundException, IOException {
|
||||||
int diff = end - start;
|
int diff = end - start;
|
||||||
byte[] bytes = new byte[1000];
|
byte[] bytes = new byte[1000];
|
||||||
BufferedInputStream bis = new BufferedInputStream(getPathFromUri(filename), 1024);
|
BufferedInputStream bis = new BufferedInputStream(FileHelper.getInputStreamFromUriString(filename, cordova), 1024);
|
||||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||||
int numRead = 0;
|
int numRead = 0;
|
||||||
|
|
||||||
@ -1001,6 +990,7 @@ public class FileUtils extends CordovaPlugin {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method to read a text file and return its contents as a byte[].
|
* Helper method to read a text file and return its contents as a byte[].
|
||||||
|
*
|
||||||
* @param filename The name of the file.
|
* @param filename The name of the file.
|
||||||
* @param start Start position in the file.
|
* @param start Start position in the file.
|
||||||
* @param end End position to stop at (exclusive).
|
* @param end End position to stop at (exclusive).
|
||||||
@ -1010,7 +1000,7 @@ public class FileUtils extends CordovaPlugin {
|
|||||||
public byte[] readAsBinary(String filename, int start, int end) throws FileNotFoundException, IOException {
|
public byte[] readAsBinary(String filename, int start, int end) throws FileNotFoundException, IOException {
|
||||||
int diff = end - start;
|
int diff = end - start;
|
||||||
byte[] bytes = new byte[1000];
|
byte[] bytes = new byte[1000];
|
||||||
BufferedInputStream bis = new BufferedInputStream(getPathFromUri(filename), 1024);
|
BufferedInputStream bis = new BufferedInputStream(FileHelper.getInputStreamFromUriString(filename, cordova), 1024);
|
||||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||||
int numRead = 0;
|
int numRead = 0;
|
||||||
|
|
||||||
@ -1029,53 +1019,21 @@ public class FileUtils extends CordovaPlugin {
|
|||||||
/**
|
/**
|
||||||
* Read content of a file and return as base64 encoded data url.
|
* Read content of a file and return as base64 encoded data url.
|
||||||
*
|
*
|
||||||
* @param filename The name of the file.
|
* @param filename The name of the file.
|
||||||
* @param start Start position in the file.
|
* @param start Start position in the file.
|
||||||
* @param end End position to stop at (exclusive).
|
* @param end End position to stop at (exclusive).
|
||||||
* @return Contents of file = data:<media type>;base64,<data>
|
* @return Contents of file = data:<media type>;base64,<data>
|
||||||
* @throws FileNotFoundException, IOException
|
* @throws FileNotFoundException, IOException
|
||||||
*/
|
*/
|
||||||
public String readAsDataURL(String filename, int start, int end) throws FileNotFoundException, IOException {
|
public String readAsDataURL(String filename, int start, int end) throws FileNotFoundException, IOException {
|
||||||
// Determine content type from file name
|
// Determine content type from file name
|
||||||
String contentType = null;
|
String contentType = FileHelper.getMimeType(filename, cordova);
|
||||||
if (filename.startsWith("content:")) {
|
|
||||||
Uri fileUri = Uri.parse(filename);
|
|
||||||
contentType = this.cordova.getActivity().getContentResolver().getType(fileUri);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
contentType = getMimeType(filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] base64 = Base64.encodeBase64(readAsBinary(filename, start, end));
|
byte[] base64 = Base64.encodeBase64(readAsBinary(filename, start, end));
|
||||||
String data = "data:" + contentType + ";base64," + new String(base64);
|
String data = "data:" + contentType + ";base64," + new String(base64);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Looks up the mime type of a given file name.
|
|
||||||
*
|
|
||||||
* @param filename
|
|
||||||
* @return a mime type
|
|
||||||
*/
|
|
||||||
public static String getMimeType(String filename) {
|
|
||||||
if (filename != null) {
|
|
||||||
// Stupid bug in getFileExtensionFromUrl when the file name has a space
|
|
||||||
// So we need to replace the space with a url encoded %20
|
|
||||||
|
|
||||||
// CB-2185: Stupid bug not putting JPG extension in the mime-type map
|
|
||||||
String url = filename.replace(" ", "%20").toLowerCase();
|
|
||||||
MimeTypeMap map = MimeTypeMap.getSingleton();
|
|
||||||
String extension = MimeTypeMap.getFileExtensionFromUrl(url);
|
|
||||||
if (extension.toLowerCase().equals("3ga")) {
|
|
||||||
return "audio/3gpp";
|
|
||||||
} else {
|
|
||||||
return map.getMimeTypeFromExtension(extension);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write contents of file.
|
* Write contents of file.
|
||||||
*
|
*
|
||||||
@ -1087,11 +1045,11 @@ public class FileUtils extends CordovaPlugin {
|
|||||||
*/
|
*/
|
||||||
/**/
|
/**/
|
||||||
public long write(String filename, String data, int offset) throws FileNotFoundException, IOException, NoModificationAllowedException {
|
public long write(String filename, String data, int offset) throws FileNotFoundException, IOException, NoModificationAllowedException {
|
||||||
if (filename.startsWith("content://")) {
|
if (filename.startsWith("content://")) {
|
||||||
throw new NoModificationAllowedException("Couldn't write to file given its content URI");
|
throw new NoModificationAllowedException("Couldn't write to file given its content URI");
|
||||||
}
|
}
|
||||||
|
|
||||||
filename = getRealPathFromURI(Uri.parse(filename), cordova);
|
filename = FileHelper.getRealPath(filename, cordova);
|
||||||
|
|
||||||
boolean append = false;
|
boolean append = false;
|
||||||
if (offset > 0) {
|
if (offset > 0) {
|
||||||
@ -1120,11 +1078,11 @@ public class FileUtils extends CordovaPlugin {
|
|||||||
* @throws NoModificationAllowedException
|
* @throws NoModificationAllowedException
|
||||||
*/
|
*/
|
||||||
private long truncateFile(String filename, long size) throws FileNotFoundException, IOException, NoModificationAllowedException {
|
private long truncateFile(String filename, long size) throws FileNotFoundException, IOException, NoModificationAllowedException {
|
||||||
if (filename.startsWith("content://")) {
|
if (filename.startsWith("content://")) {
|
||||||
throw new NoModificationAllowedException("Couldn't truncate file given its content URI");
|
throw new NoModificationAllowedException("Couldn't truncate file given its content URI");
|
||||||
}
|
}
|
||||||
|
|
||||||
filename = getRealPathFromURI(Uri.parse(filename), cordova);
|
filename = FileHelper.getRealPath(filename, cordova);
|
||||||
|
|
||||||
RandomAccessFile raf = new RandomAccessFile(filename, "rw");
|
RandomAccessFile raf = new RandomAccessFile(filename, "rw");
|
||||||
try {
|
try {
|
||||||
@ -1139,48 +1097,4 @@ public class FileUtils extends CordovaPlugin {
|
|||||||
raf.close();
|
raf.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get an input stream based on file path or content:// uri
|
|
||||||
*
|
|
||||||
* @param path
|
|
||||||
* @return an input stream
|
|
||||||
* @throws FileNotFoundException
|
|
||||||
*/
|
|
||||||
private InputStream getPathFromUri(String path) throws FileNotFoundException {
|
|
||||||
if (path.startsWith("content")) {
|
|
||||||
Uri uri = Uri.parse(path);
|
|
||||||
return cordova.getActivity().getContentResolver().openInputStream(uri);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
path = getRealPathFromURI(Uri.parse(path), cordova);
|
|
||||||
return new FileInputStream(path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Queries the media store to find out what the file path is for the Uri we supply
|
|
||||||
*
|
|
||||||
* @param contentUri the Uri of the audio/image/video
|
|
||||||
* @param cordova the current application context
|
|
||||||
* @return the full path to the file
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
protected static String getRealPathFromURI(Uri contentUri, CordovaInterface cordova) {
|
|
||||||
final String scheme = contentUri.getScheme();
|
|
||||||
|
|
||||||
if (scheme == null) {
|
|
||||||
return contentUri.toString();
|
|
||||||
} else if (scheme.compareTo("content") == 0) {
|
|
||||||
String[] proj = { _DATA };
|
|
||||||
Cursor cursor = cordova.getActivity().managedQuery(contentUri, proj, null, null, null);
|
|
||||||
int column_index = cursor.getColumnIndexOrThrow(_DATA);
|
|
||||||
cursor.moveToFirst();
|
|
||||||
return cursor.getString(column_index);
|
|
||||||
} else if (scheme.compareTo("file") == 0) {
|
|
||||||
return contentUri.getPath();
|
|
||||||
} else {
|
|
||||||
return contentUri.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user