mirror of
https://github.com/apache/cordova-android.git
synced 2025-04-22 16:50:45 +08:00
Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/incubator-cordova-android
This commit is contained in:
commit
d42489c67a
@ -133,13 +133,15 @@ var VERSION=read(ROOT+'\\VERSION').replace(/\r\n/,'').replace(/\n/,'');
|
|||||||
// create the project
|
// create the project
|
||||||
exec('android.bat create project --target '+TARGET+' --path '+PROJECT_PATH+' --package '+PACKAGE+' --activity '+ACTIVITY);
|
exec('android.bat create project --target '+TARGET+' --path '+PROJECT_PATH+' --package '+PACKAGE+' --activity '+ACTIVITY);
|
||||||
|
|
||||||
// update the cordova framework project to a target that exists on this machine
|
// build from source. distro should have these files
|
||||||
exec('android.bat update project --target '+TARGET+' --path '+ROOT+'\\framework');
|
if (!fso.FileExists(ROOT+'\\cordova-'+VERSION+'.jar') &&
|
||||||
|
!fso.FileExists(ROOT+'\\cordova-'+VERSION+'.js')) {
|
||||||
// pull down commons codec if necessary
|
// update the cordova framework project to a target that exists on this machine
|
||||||
downloadCommonsCodec();
|
exec('android.bat update project --target '+TARGET+' --path '+ROOT+'\\framework');
|
||||||
|
// pull down commons codec if necessary
|
||||||
exec('ant.bat -f '+ ROOT +'\\framework\\build.xml jar');
|
downloadCommonsCodec();
|
||||||
|
exec('ant.bat -f '+ ROOT +'\\framework\\build.xml jar');
|
||||||
|
}
|
||||||
|
|
||||||
// copy in the project template
|
// copy in the project template
|
||||||
exec('%comspec% /c xcopy '+ ROOT + '\\bin\\templates\\project\\res '+PROJECT_PATH+'\\res\\ /E /Y');
|
exec('%comspec% /c xcopy '+ ROOT + '\\bin\\templates\\project\\res '+PROJECT_PATH+'\\res\\ /E /Y');
|
||||||
@ -147,16 +149,23 @@ exec('%comspec% /c xcopy '+ ROOT + '\\bin\\templates\\project\\assets '+PROJECT_
|
|||||||
exec('%comspec% /c copy '+ROOT+'\\bin\\templates\\project\\AndroidManifest.xml ' + PROJECT_PATH + '\\AndroidManifest.xml /Y');
|
exec('%comspec% /c copy '+ROOT+'\\bin\\templates\\project\\AndroidManifest.xml ' + PROJECT_PATH + '\\AndroidManifest.xml /Y');
|
||||||
exec('%comspec% /c copy '+ROOT+'\\bin\\templates\\project\\Activity.java '+ ACTIVITY_PATH +' /Y');
|
exec('%comspec% /c copy '+ROOT+'\\bin\\templates\\project\\Activity.java '+ ACTIVITY_PATH +' /Y');
|
||||||
|
|
||||||
// copy in cordova.js
|
// check if we have the source or the distro files
|
||||||
exec('%comspec% /c copy '+ROOT+'\\framework\\assets\\www\\cordova-'+VERSION+'.js '+PROJECT_PATH+'\\assets\\www\\cordova-'+VERSION+'.js /Y');
|
if(fso.FolderExists(ROOT + '\\framework')) {
|
||||||
|
exec('%comspec% /c copy '+ROOT+'\\framework\\assets\\www\\cordova-'+VERSION+'.js '+PROJECT_PATH+'\\assets\\www\\cordova-'+VERSION+'.js /Y');
|
||||||
// copy in cordova.jar
|
exec('%comspec% /c copy '+ROOT+'\\framework\\cordova-'+VERSION+'.jar '+PROJECT_PATH+'\\libs\\cordova-'+VERSION+'.jar /Y');
|
||||||
exec('%comspec% /c copy '+ROOT+'\\framework\\cordova-'+VERSION+'.jar '+PROJECT_PATH+'\\libs\\cordova-'+VERSION+'.jar /Y');
|
fso.CreateFolder(PROJECT_PATH + '\\res\\xml');
|
||||||
|
exec('%comspec% /c copy '+ROOT+'\\framework\\res\\xml\\cordova.xml ' + PROJECT_PATH + '\\res\\xml\\cordova.xml /Y');
|
||||||
// copy in xml
|
exec('%comspec% /c copy '+ROOT+'\\framework\\res\\xml\\plugins.xml ' + PROJECT_PATH + '\\res\\xml\\plugins.xml /Y');
|
||||||
fso.CreateFolder(PROJECT_PATH + '\\res\\xml');
|
} else {
|
||||||
exec('%comspec% /c copy '+ROOT+'\\framework\\res\\xml\\cordova.xml ' + PROJECT_PATH + '\\res\\xml\\cordova.xml /Y');
|
// copy in cordova.js
|
||||||
exec('%comspec% /c copy '+ROOT+'\\framework\\res\\xml\\plugins.xml ' + PROJECT_PATH + '\\res\\xml\\plugins.xml /Y');
|
exec('%comspec% /c copy '+ROOT+'\\cordova-'+VERSION+'.js '+PROJECT_PATH+'\\assets\\www\\cordova-'+VERSION+'.js /Y');
|
||||||
|
// copy in cordova.jar
|
||||||
|
exec('%comspec% /c copy '+ROOT+'\\cordova-'+VERSION+'.jar '+PROJECT_PATH+'\\libs\\cordova-'+VERSION+'.jar /Y');
|
||||||
|
// copy in xml
|
||||||
|
fso.CreateFolder(PROJECT_PATH + '\\res\\xml');
|
||||||
|
exec('%comspec% /c copy '+ROOT+'\\xml\\cordova.xml ' + PROJECT_PATH + '\\res\\xml\\cordova.xml /Y');
|
||||||
|
exec('%comspec% /c copy '+ROOT+'\\xml\\plugins.xml ' + PROJECT_PATH + '\\res\\xml\\plugins.xml /Y');
|
||||||
|
}
|
||||||
|
|
||||||
// copy cordova scripts
|
// copy cordova scripts
|
||||||
fso.CreateFolder(PROJECT_PATH + '\\cordova');
|
fso.CreateFolder(PROJECT_PATH + '\\cordova');
|
||||||
|
4
bin/templates/cordova/cordova.js
vendored
4
bin/templates/cordova/cordova.js
vendored
@ -8,7 +8,7 @@ function exec(command) {
|
|||||||
if(!oExec.StdOut.AtEndOfStream) {
|
if(!oExec.StdOut.AtEndOfStream) {
|
||||||
var line = oExec.StdOut.ReadLine();
|
var line = oExec.StdOut.ReadLine();
|
||||||
// XXX: Change to verbose mode
|
// XXX: Change to verbose mode
|
||||||
//WScript.StdOut.WriteLine(line);
|
// WScript.StdOut.WriteLine(line);
|
||||||
output += line;
|
output += line;
|
||||||
}
|
}
|
||||||
WScript.sleep(100);
|
WScript.sleep(100);
|
||||||
@ -79,7 +79,7 @@ function debug_install() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function log() {
|
function log() {
|
||||||
WScript.Echo(exec("%comspec% /c adb.bat logcat"));
|
shell.Run("%comspec% /c adb logcat");
|
||||||
}
|
}
|
||||||
|
|
||||||
function launch() {
|
function launch() {
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
%~dp0\cordova.bat log
|
@ -12,3 +12,4 @@ split.density=false
|
|||||||
# Project target.
|
# Project target.
|
||||||
target=Google Inc.:Google APIs:15
|
target=Google Inc.:Google APIs:15
|
||||||
apk-configurations=
|
apk-configurations=
|
||||||
|
renderscript.opt.level=O0
|
||||||
|
@ -40,6 +40,7 @@ import android.content.ContentValues;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.BitmapFactory;
|
||||||
import android.graphics.Matrix;
|
import android.graphics.Matrix;
|
||||||
import android.graphics.Bitmap.CompressFormat;
|
import android.graphics.Bitmap.CompressFormat;
|
||||||
import android.media.MediaScannerConnection;
|
import android.media.MediaScannerConnection;
|
||||||
@ -82,6 +83,7 @@ public class CameraLauncher extends Plugin implements MediaScannerConnectionClie
|
|||||||
private int encodingType; // Type of encoding to use
|
private int encodingType; // Type of encoding to use
|
||||||
private int mediaType; // What type of media to retrieve
|
private int mediaType; // What type of media to retrieve
|
||||||
private boolean saveToPhotoAlbum; // Should the picture be saved to the device's photo album
|
private boolean saveToPhotoAlbum; // Should the picture be saved to the device's photo album
|
||||||
|
private boolean correctOrientation; // Should the pictures orientation be corrected
|
||||||
|
|
||||||
public String callbackId;
|
public String callbackId;
|
||||||
private int numPics;
|
private int numPics;
|
||||||
@ -136,6 +138,7 @@ public class CameraLauncher extends Plugin implements MediaScannerConnectionClie
|
|||||||
this.targetHeight = args.getInt(4);
|
this.targetHeight = args.getInt(4);
|
||||||
this.encodingType = args.getInt(5);
|
this.encodingType = args.getInt(5);
|
||||||
this.mediaType = args.getInt(6);
|
this.mediaType = args.getInt(6);
|
||||||
|
this.correctOrientation = args.getBoolean(8);
|
||||||
this.saveToPhotoAlbum = args.getBoolean(9);
|
this.saveToPhotoAlbum = args.getBoolean(9);
|
||||||
|
|
||||||
if (srcType == CAMERA) {
|
if (srcType == CAMERA) {
|
||||||
@ -181,7 +184,6 @@ public class CameraLauncher extends Plugin implements MediaScannerConnectionClie
|
|||||||
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
|
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
|
||||||
|
|
||||||
// Specify file so that large image is captured and returned
|
// Specify file so that large image is captured and returned
|
||||||
// TODO: What if there isn't any external storage?
|
|
||||||
File photo = createCaptureFile(encodingType);
|
File photo = createCaptureFile(encodingType);
|
||||||
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, Uri.fromFile(photo));
|
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, Uri.fromFile(photo));
|
||||||
this.imageUri = Uri.fromFile(photo);
|
this.imageUri = Uri.fromFile(photo);
|
||||||
@ -244,53 +246,6 @@ public class CameraLauncher extends Plugin implements MediaScannerConnectionClie
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Scales the bitmap according to the requested size.
|
|
||||||
*
|
|
||||||
* @param bitmap The bitmap to scale.
|
|
||||||
* @return Bitmap A new Bitmap object of the same bitmap after scaling.
|
|
||||||
*/
|
|
||||||
public Bitmap scaleBitmap(Bitmap bitmap) {
|
|
||||||
int newWidth = this.targetWidth;
|
|
||||||
int newHeight = this.targetHeight;
|
|
||||||
int origWidth = bitmap.getWidth();
|
|
||||||
int origHeight = bitmap.getHeight();
|
|
||||||
|
|
||||||
// If no new width or height were specified return the original bitmap
|
|
||||||
if (newWidth <= 0 && newHeight <= 0) {
|
|
||||||
return bitmap;
|
|
||||||
}
|
|
||||||
// Only the width was specified
|
|
||||||
else if (newWidth > 0 && newHeight <= 0) {
|
|
||||||
newHeight = (newWidth * origHeight) / origWidth;
|
|
||||||
}
|
|
||||||
// only the height was specified
|
|
||||||
else if (newWidth <= 0 && newHeight > 0) {
|
|
||||||
newWidth = (newHeight * origWidth) / origHeight;
|
|
||||||
}
|
|
||||||
// If the user specified both a positive width and height
|
|
||||||
// (potentially different aspect ratio) then the width or height is
|
|
||||||
// scaled so that the image fits while maintaining aspect ratio.
|
|
||||||
// Alternatively, the specified width and height could have been
|
|
||||||
// kept and Bitmap.SCALE_TO_FIT specified when scaling, but this
|
|
||||||
// would result in whitespace in the new image.
|
|
||||||
else {
|
|
||||||
double newRatio = newWidth / (double) newHeight;
|
|
||||||
double origRatio = origWidth / (double) origHeight;
|
|
||||||
|
|
||||||
if (origRatio > newRatio) {
|
|
||||||
newHeight = (newWidth * origHeight) / origWidth;
|
|
||||||
} else if (origRatio < newRatio) {
|
|
||||||
newWidth = (newHeight * origWidth) / origHeight;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Bitmap retval = Bitmap.createScaledBitmap(bitmap, newWidth, newHeight, true);
|
|
||||||
bitmap.recycle();
|
|
||||||
System.gc();
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when the camera view exits.
|
* Called when the camera view exits.
|
||||||
*
|
*
|
||||||
@ -312,6 +267,7 @@ public class CameraLauncher extends Plugin implements MediaScannerConnectionClie
|
|||||||
if (this.encodingType == JPEG) {
|
if (this.encodingType == JPEG) {
|
||||||
exif.createInFile(DirectoryManager.getTempDirectoryPath(this.cordova.getActivity()) + "/.Pic.jpg");
|
exif.createInFile(DirectoryManager.getTempDirectoryPath(this.cordova.getActivity()) + "/.Pic.jpg");
|
||||||
exif.readExifData();
|
exif.readExifData();
|
||||||
|
rotate = exif.getOrientation();
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@ -325,7 +281,11 @@ public class CameraLauncher extends Plugin implements MediaScannerConnectionClie
|
|||||||
|
|
||||||
// If sending base64 image back
|
// If sending base64 image back
|
||||||
if (destType == DATA_URL) {
|
if (destType == DATA_URL) {
|
||||||
bitmap = scaleBitmap(getBitmapFromResult(intent));
|
bitmap = getScaledBitmap(FileUtils.stripFileProtocol(imageUri.toString()));
|
||||||
|
|
||||||
|
if (rotate != 0 && this.correctOrientation) {
|
||||||
|
bitmap = getRotatedBitmap(rotate, bitmap, exif);
|
||||||
|
}
|
||||||
|
|
||||||
this.processPicture(bitmap);
|
this.processPicture(bitmap);
|
||||||
checkForDuplicateImage(DATA_URL);
|
checkForDuplicateImage(DATA_URL);
|
||||||
@ -337,42 +297,24 @@ public class CameraLauncher extends Plugin implements MediaScannerConnectionClie
|
|||||||
if (!this.saveToPhotoAlbum) {
|
if (!this.saveToPhotoAlbum) {
|
||||||
uri = Uri.fromFile(new File("/data/data/" + this.cordova.getActivity().getPackageName() + "/", (new File(FileUtils.stripFileProtocol(this.imageUri.toString()))).getName()));
|
uri = Uri.fromFile(new File("/data/data/" + this.cordova.getActivity().getPackageName() + "/", (new File(FileUtils.stripFileProtocol(this.imageUri.toString()))).getName()));
|
||||||
} else {
|
} else {
|
||||||
// Create entry in media store for image
|
uri = getUriFromMediaStore();
|
||||||
// (Don't use insertImage() because it uses default compression setting of 50 - no way to change it)
|
}
|
||||||
ContentValues values = new ContentValues();
|
|
||||||
values.put(android.provider.MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
|
|
||||||
|
|
||||||
try {
|
if (uri == null) {
|
||||||
uri = this.cordova.getActivity().getContentResolver().insert(android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
|
|
||||||
} catch (UnsupportedOperationException e) {
|
|
||||||
LOG.d(LOG_TAG, "Can't write to external media storage.");
|
|
||||||
try {
|
|
||||||
uri = this.cordova.getActivity().getContentResolver().insert(android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI, values);
|
|
||||||
} catch (UnsupportedOperationException ex) {
|
|
||||||
LOG.d(LOG_TAG, "Can't write to internal media storage.");
|
|
||||||
this.failPicture("Error capturing image - no media storage found.");
|
this.failPicture("Error capturing image - no media storage found.");
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If all this is true we shouldn't compress the image.
|
// If all this is true we shouldn't compress the image.
|
||||||
if (this.targetHeight == -1 && this.targetWidth == -1 && this.mQuality == 100) {
|
if (this.targetHeight == -1 && this.targetWidth == -1 && this.mQuality == 100 && rotate == 0) {
|
||||||
FileInputStream fis = new FileInputStream(FileUtils.stripFileProtocol(imageUri.toString()));
|
writeUncompressedImage(uri);
|
||||||
OutputStream os = this.cordova.getActivity().getContentResolver().openOutputStream(uri);
|
|
||||||
byte[] buffer = new byte[4096];
|
|
||||||
int len;
|
|
||||||
while ((len = fis.read(buffer)) != -1) {
|
|
||||||
os.write(buffer, 0, len);
|
|
||||||
}
|
|
||||||
os.flush();
|
|
||||||
os.close();
|
|
||||||
fis.close();
|
|
||||||
|
|
||||||
this.success(new PluginResult(PluginResult.Status.OK, uri.toString()), this.callbackId);
|
this.success(new PluginResult(PluginResult.Status.OK, uri.toString()), this.callbackId);
|
||||||
} else {
|
} else {
|
||||||
|
bitmap = getScaledBitmap(FileUtils.stripFileProtocol(imageUri.toString()));
|
||||||
|
|
||||||
bitmap = scaleBitmap(getBitmapFromResult(intent));
|
if (rotate != 0 && this.correctOrientation) {
|
||||||
|
bitmap = getRotatedBitmap(rotate, bitmap, exif);
|
||||||
|
}
|
||||||
|
|
||||||
// Add compressed version of captured image to returned media store Uri
|
// Add compressed version of captured image to returned media store Uri
|
||||||
OutputStream os = this.cordova.getActivity().getContentResolver().openOutputStream(uri);
|
OutputStream os = this.cordova.getActivity().getContentResolver().openOutputStream(uri);
|
||||||
@ -394,7 +336,13 @@ public class CameraLauncher extends Plugin implements MediaScannerConnectionClie
|
|||||||
|
|
||||||
}
|
}
|
||||||
// Send Uri back to JavaScript for viewing image
|
// Send Uri back to JavaScript for viewing image
|
||||||
|
if (saveToPhotoAlbum) {
|
||||||
this.success(new PluginResult(PluginResult.Status.OK, uri.toString()), this.callbackId);
|
this.success(new PluginResult(PluginResult.Status.OK, uri.toString()), this.callbackId);
|
||||||
|
} else {
|
||||||
|
// If you don't want to save the file to the photo album you need to append a timestamp
|
||||||
|
// to the returned URI to do some cache busting.
|
||||||
|
this.success(new PluginResult(PluginResult.Status.OK, uri.toString() + "?" + System.currentTimeMillis()), this.callbackId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.cleanup(FILE_URI, this.imageUri, bitmap);
|
this.cleanup(FILE_URI, this.imageUri, bitmap);
|
||||||
@ -421,7 +369,6 @@ public class CameraLauncher extends Plugin implements MediaScannerConnectionClie
|
|||||||
else if ((srcType == PHOTOLIBRARY) || (srcType == SAVEDPHOTOALBUM)) {
|
else if ((srcType == PHOTOLIBRARY) || (srcType == SAVEDPHOTOALBUM)) {
|
||||||
if (resultCode == Activity.RESULT_OK) {
|
if (resultCode == Activity.RESULT_OK) {
|
||||||
Uri uri = intent.getData();
|
Uri uri = intent.getData();
|
||||||
android.content.ContentResolver resolver = this.cordova.getActivity().getContentResolver();
|
|
||||||
|
|
||||||
// If you ask for video or all media type you will automatically get back a file URI
|
// If you ask for video or all media type you will automatically get back a file URI
|
||||||
// and there will be no attempt to resize any returned data
|
// and there will be no attempt to resize any returned data
|
||||||
@ -429,10 +376,13 @@ public class CameraLauncher extends Plugin implements MediaScannerConnectionClie
|
|||||||
this.success(new PluginResult(PluginResult.Status.OK, uri.toString()), this.callbackId);
|
this.success(new PluginResult(PluginResult.Status.OK, uri.toString()), this.callbackId);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
|
// Get the path to the image. Makes loading so much easier.
|
||||||
|
String imagePath = FileUtils.getRealPathFromURI(uri, this.cordova);
|
||||||
|
Bitmap bitmap = getScaledBitmap(imagePath);
|
||||||
|
|
||||||
// If sending base64 image back
|
// If sending base64 image back
|
||||||
if (destType == DATA_URL) {
|
if (destType == DATA_URL) {
|
||||||
try {
|
|
||||||
Bitmap bitmap = android.graphics.BitmapFactory.decodeStream(resolver.openInputStream(uri));
|
|
||||||
String[] cols = { MediaStore.Images.Media.ORIENTATION };
|
String[] cols = { MediaStore.Images.Media.ORIENTATION };
|
||||||
Cursor cursor = this.cordova.getActivity().getContentResolver().query(intent.getData(),
|
Cursor cursor = this.cordova.getActivity().getContentResolver().query(intent.getData(),
|
||||||
cols,
|
cols,
|
||||||
@ -447,15 +397,7 @@ public class CameraLauncher extends Plugin implements MediaScannerConnectionClie
|
|||||||
matrix.setRotate(rotate);
|
matrix.setRotate(rotate);
|
||||||
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
|
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
|
||||||
}
|
}
|
||||||
bitmap = scaleBitmap(bitmap);
|
|
||||||
this.processPicture(bitmap);
|
this.processPicture(bitmap);
|
||||||
bitmap.recycle();
|
|
||||||
bitmap = null;
|
|
||||||
System.gc();
|
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
this.failPicture("Error retrieving image.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If sending filename back
|
// If sending filename back
|
||||||
@ -463,8 +405,6 @@ public class CameraLauncher extends Plugin implements MediaScannerConnectionClie
|
|||||||
// Do we need to scale the returned file
|
// Do we need to scale the returned file
|
||||||
if (this.targetHeight > 0 && this.targetWidth > 0) {
|
if (this.targetHeight > 0 && this.targetWidth > 0) {
|
||||||
try {
|
try {
|
||||||
Bitmap bitmap = android.graphics.BitmapFactory.decodeStream(resolver.openInputStream(uri));
|
|
||||||
bitmap = scaleBitmap(bitmap);
|
|
||||||
|
|
||||||
String fileName = DirectoryManager.getTempDirectoryPath(this.cordova.getActivity()) + "/resize.jpg";
|
String fileName = DirectoryManager.getTempDirectoryPath(this.cordova.getActivity()) + "/resize.jpg";
|
||||||
OutputStream os = new FileOutputStream(fileName);
|
OutputStream os = new FileOutputStream(fileName);
|
||||||
@ -477,13 +417,9 @@ public class CameraLauncher extends Plugin implements MediaScannerConnectionClie
|
|||||||
exif.writeExifData();
|
exif.writeExifData();
|
||||||
}
|
}
|
||||||
|
|
||||||
bitmap.recycle();
|
|
||||||
bitmap = null;
|
|
||||||
|
|
||||||
// The resized image is cached by the app in order to get around this and not have to delete you
|
// The resized image is cached by the app in order to get around this and not have to delete you
|
||||||
// application cache I'm adding the current system time to the end of the file url.
|
// application cache I'm adding the current system time to the end of the file url.
|
||||||
this.success(new PluginResult(PluginResult.Status.OK, ("file://" + fileName + "?" + System.currentTimeMillis())), this.callbackId);
|
this.success(new PluginResult(PluginResult.Status.OK, ("file://" + fileName + "?" + System.currentTimeMillis())), this.callbackId);
|
||||||
System.gc();
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
this.failPicture("Error retrieving image.");
|
this.failPicture("Error retrieving image.");
|
||||||
@ -493,6 +429,9 @@ public class CameraLauncher extends Plugin implements MediaScannerConnectionClie
|
|||||||
this.success(new PluginResult(PluginResult.Status.OK, uri.toString()), this.callbackId);
|
this.success(new PluginResult(PluginResult.Status.OK, uri.toString()), this.callbackId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
bitmap.recycle();
|
||||||
|
bitmap = null;
|
||||||
|
System.gc();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (resultCode == Activity.RESULT_CANCELED) {
|
else if (resultCode == Activity.RESULT_CANCELED) {
|
||||||
@ -504,19 +443,108 @@ public class CameraLauncher extends Plugin implements MediaScannerConnectionClie
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Bitmap getBitmapFromResult(Intent intent)
|
/**
|
||||||
throws IOException, FileNotFoundException {
|
* Figure out if the bitmap should be rotated. For instance if the picture was taken in
|
||||||
Bitmap bitmap = null;
|
* portrait mode
|
||||||
try {
|
*
|
||||||
bitmap = android.provider.MediaStore.Images.Media.getBitmap(this.ctx.getActivity().getContentResolver(), imageUri);
|
* @param rotate
|
||||||
} catch (FileNotFoundException e) {
|
* @param bitmap
|
||||||
Uri uri = intent.getData();
|
* @return rotated bitmap
|
||||||
android.content.ContentResolver resolver = this.ctx.getActivity().getContentResolver();
|
*/
|
||||||
bitmap = android.graphics.BitmapFactory.decodeStream(resolver.openInputStream(uri));
|
private Bitmap getRotatedBitmap(int rotate, Bitmap bitmap, ExifHelper exif) {
|
||||||
|
Matrix matrix = new Matrix();
|
||||||
|
if (rotate == 180) {
|
||||||
|
matrix.setRotate(rotate);
|
||||||
|
} else {
|
||||||
|
matrix.setRotate(rotate, (float) bitmap.getWidth() / 2, (float) bitmap.getHeight() / 2);
|
||||||
}
|
}
|
||||||
|
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
|
||||||
|
exif.resetOrientation();
|
||||||
return bitmap;
|
return bitmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In the special case where the default width, height and quality are unchanged
|
||||||
|
* we just write the file out to disk saving the expensive Bitmap.compress function.
|
||||||
|
*
|
||||||
|
* @param uri
|
||||||
|
* @throws FileNotFoundException
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
private void writeUncompressedImage(Uri uri) throws FileNotFoundException,
|
||||||
|
IOException {
|
||||||
|
FileInputStream fis = new FileInputStream(FileUtils.stripFileProtocol(imageUri.toString()));
|
||||||
|
OutputStream os = this.cordova.getActivity().getContentResolver().openOutputStream(uri);
|
||||||
|
byte[] buffer = new byte[4096];
|
||||||
|
int len;
|
||||||
|
while ((len = fis.read(buffer)) != -1) {
|
||||||
|
os.write(buffer, 0, len);
|
||||||
|
}
|
||||||
|
os.flush();
|
||||||
|
os.close();
|
||||||
|
fis.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create entry in media store for image
|
||||||
|
*
|
||||||
|
* @return uri
|
||||||
|
*/
|
||||||
|
private Uri getUriFromMediaStore() {
|
||||||
|
ContentValues values = new ContentValues();
|
||||||
|
values.put(android.provider.MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
|
||||||
|
Uri uri;
|
||||||
|
try {
|
||||||
|
uri = this.cordova.getActivity().getContentResolver().insert(android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
|
||||||
|
} catch (UnsupportedOperationException e) {
|
||||||
|
LOG.d(LOG_TAG, "Can't write to external media storage.");
|
||||||
|
try {
|
||||||
|
uri = this.cordova.getActivity().getContentResolver().insert(android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI, values);
|
||||||
|
} catch (UnsupportedOperationException ex) {
|
||||||
|
LOG.d(LOG_TAG, "Can't write to internal media storage.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a scaled bitmap based on the target width and height
|
||||||
|
*
|
||||||
|
* @param imagePath
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private Bitmap getScaledBitmap(String imagePath) {
|
||||||
|
// If no new width or height were specified return the original bitmap
|
||||||
|
if (this.targetWidth <= 0 && this.targetHeight <= 0) {
|
||||||
|
return BitmapFactory.decodeFile(imagePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
Bitmap unscaledBitmap = decodeFile(imagePath,
|
||||||
|
this.targetWidth, this.targetHeight);
|
||||||
|
return Bitmap.createScaledBitmap(unscaledBitmap, this.targetWidth, this.targetHeight, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Bitmap decodeFile(String pathName, int dstWidth, int dstHeight) {
|
||||||
|
BitmapFactory.Options options = new BitmapFactory.Options();
|
||||||
|
options.inJustDecodeBounds = true;
|
||||||
|
BitmapFactory.decodeFile(pathName, options);
|
||||||
|
options.inJustDecodeBounds = false;
|
||||||
|
options.inSampleSize = calculateSampleSize(options.outWidth, options.outHeight, dstWidth, dstHeight);
|
||||||
|
return BitmapFactory.decodeFile(pathName, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int calculateSampleSize(int srcWidth, int srcHeight, int dstWidth, int dstHeight) {
|
||||||
|
final float srcAspect = (float)srcWidth / (float)srcHeight;
|
||||||
|
final float dstAspect = (float)dstWidth / (float)dstHeight;
|
||||||
|
|
||||||
|
if (srcAspect > dstAspect) {
|
||||||
|
return srcWidth / dstWidth;
|
||||||
|
} else {
|
||||||
|
return srcHeight / dstHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a cursor that can be used to determine how many images we have.
|
* Creates a cursor that can be used to determine how many images we have.
|
||||||
*
|
*
|
||||||
@ -535,7 +563,9 @@ public class CameraLauncher extends Plugin implements MediaScannerConnectionClie
|
|||||||
* Cleans up after picture taking. Checking for duplicates and that kind of stuff.
|
* Cleans up after picture taking. Checking for duplicates and that kind of stuff.
|
||||||
*/
|
*/
|
||||||
private void cleanup(int imageType, Uri oldImage, Bitmap bitmap) {
|
private void cleanup(int imageType, Uri oldImage, Bitmap bitmap) {
|
||||||
|
if (bitmap != null) {
|
||||||
bitmap.recycle();
|
bitmap.recycle();
|
||||||
|
}
|
||||||
|
|
||||||
// Clean up initial camera-written image file.
|
// Clean up initial camera-written image file.
|
||||||
(new File(FileUtils.stripFileProtocol(oldImage.toString()))).delete();
|
(new File(FileUtils.stripFileProtocol(oldImage.toString()))).delete();
|
||||||
@ -560,7 +590,7 @@ public class CameraLauncher extends Plugin implements MediaScannerConnectionClie
|
|||||||
Cursor cursor = queryImgDB(contentStore);
|
Cursor cursor = queryImgDB(contentStore);
|
||||||
int currentNumOfImages = cursor.getCount();
|
int currentNumOfImages = cursor.getCount();
|
||||||
|
|
||||||
if (type == FILE_URI) {
|
if (type == FILE_URI && this.saveToPhotoAlbum) {
|
||||||
diff = 2;
|
diff = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,4 +162,24 @@ public class ExifHelper {
|
|||||||
|
|
||||||
this.outFile.saveAttributes();
|
this.outFile.saveAttributes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getOrientation() {
|
||||||
|
int o = Integer.parseInt(this.orientation);
|
||||||
|
|
||||||
|
if (o == ExifInterface.ORIENTATION_NORMAL) {
|
||||||
|
return 0;
|
||||||
|
} else if (o == ExifInterface.ORIENTATION_ROTATE_90) {
|
||||||
|
return 90;
|
||||||
|
} else if (o == ExifInterface.ORIENTATION_ROTATE_180) {
|
||||||
|
return 180;
|
||||||
|
} else if (o == ExifInterface.ORIENTATION_ROTATE_270) {
|
||||||
|
return 270;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resetOrientation() {
|
||||||
|
this.orientation = "" + ExifInterface.ORIENTATION_NORMAL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ import java.io.InputStream;
|
|||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.net.URLDecoder;
|
||||||
import java.security.cert.CertificateException;
|
import java.security.cert.CertificateException;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
@ -73,7 +74,7 @@ public class FileTransfer extends Plugin {
|
|||||||
String source = null;
|
String source = null;
|
||||||
String target = null;
|
String target = null;
|
||||||
try {
|
try {
|
||||||
source = args.getString(0);
|
source = URLDecoder.decode(args.getString(0));
|
||||||
target = args.getString(1);
|
target = args.getString(1);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
Log.d(LOG_TAG, "Missing source or target");
|
Log.d(LOG_TAG, "Missing source or target");
|
||||||
@ -321,7 +322,7 @@ public class FileTransfer extends Plugin {
|
|||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
// Shouldn't happen, but will
|
// Shouldn't happen, but will
|
||||||
JSONObject error = createFileTransferError(CONNECTION_ERR, source, target, conn);
|
JSONObject error = createFileTransferError(CONNECTION_ERR, source, target, conn);
|
||||||
Log.wtf(LOG_TAG, error.toString(), t);
|
Log.e(LOG_TAG, error.toString(), t);
|
||||||
return new PluginResult(PluginResult.Status.IO_EXCEPTION, error);
|
return new PluginResult(PluginResult.Status.IO_EXCEPTION, error);
|
||||||
} finally {
|
} finally {
|
||||||
if (conn != null) {
|
if (conn != null) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user