mirror of
https://github.com/apache/cordova-android.git
synced 2026-01-30 00:05:28 +08:00
Compare commits
33 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fba87de064 | ||
|
|
576f8cba44 | ||
|
|
b9f9429542 | ||
|
|
bf0df9f3c3 | ||
|
|
1d458f2782 | ||
|
|
5ca4b4a884 | ||
|
|
5935052ead | ||
|
|
f3f2ad9144 | ||
|
|
9d1edc4554 | ||
|
|
5143b8a492 | ||
|
|
7c67f40fc4 | ||
|
|
167b600135 | ||
|
|
6c465e25d3 | ||
|
|
c183d06ed1 | ||
|
|
574731b853 | ||
|
|
94568a4ec8 | ||
|
|
b22c0e5b6d | ||
|
|
ab3347d25d | ||
|
|
66872de8e5 | ||
|
|
f6d4402fdc | ||
|
|
9f66ccb5f3 | ||
|
|
b339330592 | ||
|
|
6f8e13297e | ||
|
|
e9a9144098 | ||
|
|
d1905dbee8 | ||
|
|
adc88f01b7 | ||
|
|
ccf0c5db67 | ||
|
|
f394f7457b | ||
|
|
40b9810a63 | ||
|
|
dffd2deb53 | ||
|
|
8ff48b371e | ||
|
|
6de66b87cb | ||
|
|
45680a562e |
@@ -33,6 +33,10 @@ function read(filename) {
|
||||
f.Close();
|
||||
return s;
|
||||
}
|
||||
function setTarget() {
|
||||
var targets = shell.Exec('android.bat list targets').StdOut.ReadAll().match(/id:\s\d+/g);
|
||||
return targets[targets.length - 1].replace(/id: /, ""); // TODO: give users the option to set their target
|
||||
}
|
||||
function write(filename, contents) {
|
||||
var fso=WScript.CreateObject("Scripting.FileSystemObject");
|
||||
var f=fso.OpenTextFile(filename, 2, true);
|
||||
@@ -42,12 +46,11 @@ function write(filename, contents) {
|
||||
function replaceInFile(filename, regexp, replacement) {
|
||||
write(filename, read(filename).replace(regexp, replacement));
|
||||
}
|
||||
function exec(s, output) {
|
||||
var o=shell.Exec(s);
|
||||
while (o.Status == 0) {
|
||||
WScript.Sleep(100);
|
||||
function exec(command) {
|
||||
var oShell=shell.Exec(command);
|
||||
while (oShell.Status == 0) {
|
||||
WScript.sleep(100);
|
||||
}
|
||||
//WScript.Echo("Command exited with code " + o.Status);
|
||||
}
|
||||
|
||||
function cleanup() {
|
||||
@@ -125,9 +128,8 @@ if(fso.FolderExists(PROJECT_PATH)) {
|
||||
var PACKAGE_AS_PATH=PACKAGE.replace(/\./g, '\\');
|
||||
var ACTIVITY_PATH=PROJECT_PATH+'\\src\\'+PACKAGE_AS_PATH+'\\'+ACTIVITY+'.java';
|
||||
var MANIFEST_PATH=PROJECT_PATH+'\\AndroidManifest.xml';
|
||||
var TARGET=shell.Exec('android.bat list targets').StdOut.ReadAll().match(/id:\s([0-9]).*/)[1];
|
||||
var TARGET=setTarget();
|
||||
var VERSION=read(ROOT+'\\VERSION').replace(/\r\n/,'').replace(/\n/,'');
|
||||
|
||||
// create the project
|
||||
exec('android.bat create project --target '+TARGET+' --path '+PROJECT_PATH+' --package '+PACKAGE+' --activity '+ACTIVITY);
|
||||
|
||||
@@ -140,18 +142,32 @@ downloadCommonsCodec();
|
||||
exec('ant.bat -f '+ ROOT +'\\framework\\build.xml jar');
|
||||
|
||||
// copy in the project template
|
||||
exec('cmd /c xcopy '+ ROOT + '\\bin\\templates\\project\\* '+PROJECT_PATH+' /S /Y');
|
||||
exec('%comspec% /c xcopy '+ ROOT + '\\bin\\templates\\project\\res '+PROJECT_PATH+'\\res\\ /E /Y');
|
||||
exec('%comspec% /c xcopy '+ ROOT + '\\bin\\templates\\project\\assets '+PROJECT_PATH+'\\assets\\ /E /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');
|
||||
|
||||
// copy in cordova.js
|
||||
exec('cmd /c copy '+ROOT+'\\framework\\assets\\www\\cordova-'+VERSION+'.js '+PROJECT_PATH+'\\assets\\www\\cordova-'+VERSION+'.js /Y');
|
||||
exec('%comspec% /c copy '+ROOT+'\\framework\\assets\\www\\cordova-'+VERSION+'.js '+PROJECT_PATH+'\\assets\\www\\cordova-'+VERSION+'.js /Y');
|
||||
|
||||
// copy in cordova.jar
|
||||
exec('cmd /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');
|
||||
|
||||
// copy in xml
|
||||
fso.CreateFolder(PROJECT_PATH + '\\res\\xml');
|
||||
exec('cmd /c copy '+ROOT+'\\framework\\res\\xml\\cordova.xml ' + PROJECT_PATH + '\\res\\xml\\cordova.xml /Y');
|
||||
exec('cmd /c copy '+ROOT+'\\framework\\res\\xml\\plugins.xml ' + PROJECT_PATH + '\\res\\xml\\plugins.xml /Y');
|
||||
exec('%comspec% /c copy '+ROOT+'\\framework\\res\\xml\\cordova.xml ' + PROJECT_PATH + '\\res\\xml\\cordova.xml /Y');
|
||||
exec('%comspec% /c copy '+ROOT+'\\framework\\res\\xml\\plugins.xml ' + PROJECT_PATH + '\\res\\xml\\plugins.xml /Y');
|
||||
|
||||
// copy cordova scripts
|
||||
fso.CreateFolder(PROJECT_PATH + '\\cordova');
|
||||
exec('%comspec% /c copy '+ROOT+'\\bin\\templates\\cordova\\appinfo.jar ' + PROJECT_PATH + '\\cordova\\appinfo.jar /Y');
|
||||
exec('%comspec% /c copy '+ROOT+'\\bin\\templates\\cordova\\cordova.js ' + PROJECT_PATH + '\\cordova\\cordova.js /Y');
|
||||
exec('%comspec% /c copy '+ROOT+'\\bin\\templates\\cordova\\cordova.bat ' + PROJECT_PATH + '\\cordova\\cordova.bat /Y');
|
||||
exec('%comspec% /c copy '+ROOT+'\\bin\\templates\\cordova\\clean.bat ' + PROJECT_PATH + '\\cordova\\clean.bat /Y');
|
||||
exec('%comspec% /c copy '+ROOT+'\\bin\\templates\\cordova\\debug.bat ' + PROJECT_PATH + '\\cordova\\debug.bat /Y');
|
||||
exec('%comspec% /c copy '+ROOT+'\\bin\\templates\\cordova\\log.bat ' + PROJECT_PATH + '\\cordova\\log.bat /Y');
|
||||
exec('%comspec% /c copy '+ROOT+'\\bin\\templates\\cordova\\emulate.bat ' + PROJECT_PATH + '\\cordova\\emulate.bat /Y');
|
||||
exec('%comspec% /c copy '+ROOT+'\\bin\\templates\\cordova\\BOOM.bat ' + PROJECT_PATH + '\\cordova\\BOOM.bat /Y');
|
||||
|
||||
// interpolate the activity name and package
|
||||
replaceInFile(ACTIVITY_PATH, /__ACTIVITY__/, ACTIVITY);
|
||||
|
||||
Binary file not shown.
@@ -21,7 +21,7 @@ public class ApplicationInfo {
|
||||
|
||||
// getting activity name
|
||||
String activity = ((Element)dom.getElementsByTagName("activity").item(0)).getAttribute("android:name");
|
||||
System.out.println(String.format("%s/%s.%s", pakkage, pakkage, activity));
|
||||
System.out.println(String.format("%s/.%s", pakkage, activity.replace(".", "")));
|
||||
} catch(ParserConfigurationException pce) {
|
||||
pce.printStackTrace();
|
||||
} catch(SAXException se) {
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
Main-Class: ApplicationInfo
|
||||
1
bin/templates/cordova/BOOM.bat
Normal file
1
bin/templates/cordova/BOOM.bat
Normal file
@@ -0,0 +1 @@
|
||||
%~dp0\cordova.bat BOOM
|
||||
Binary file not shown.
1
bin/templates/cordova/clean.bat
Normal file
1
bin/templates/cordova/clean.bat
Normal file
@@ -0,0 +1 @@
|
||||
%~dp0\cordova.bat clean
|
||||
15
bin/templates/cordova/cordova.bat
Normal file
15
bin/templates/cordova/cordova.bat
Normal file
@@ -0,0 +1,15 @@
|
||||
@ECHO OFF
|
||||
IF NOT DEFINED JAVA_HOME GOTO MISSING
|
||||
FOR %%X in (java.exe ant.bat android.bat) do (
|
||||
SET FOUND=%%~$PATH:X
|
||||
IF NOT DEFINED FOUND GOTO MISSING
|
||||
)
|
||||
cscript %~dp0\cordova.js %*
|
||||
GOTO END
|
||||
:MISSING
|
||||
ECHO Missing one of the following:
|
||||
ECHO JDK: http://java.oracle.com
|
||||
ECHO Android SDK: http://developer.android.com
|
||||
ECHO Apache ant: http://ant.apache.org
|
||||
EXIT /B 1
|
||||
:END
|
||||
108
bin/templates/cordova/cordova.js
vendored
Normal file
108
bin/templates/cordova/cordova.js
vendored
Normal file
@@ -0,0 +1,108 @@
|
||||
var ROOT = WScript.ScriptFullName.split('\\cordova\\cordova.js').join(''),
|
||||
shell=WScript.CreateObject("WScript.Shell");
|
||||
|
||||
function exec(command) {
|
||||
var oExec=shell.Exec(command);
|
||||
var output = new String();
|
||||
while(oExec.Status == 0) {
|
||||
if(!oExec.StdOut.AtEndOfStream) {
|
||||
var line = oExec.StdOut.ReadLine();
|
||||
// XXX: Change to verbose mode
|
||||
//WScript.StdOut.WriteLine(line);
|
||||
output += line;
|
||||
}
|
||||
WScript.sleep(100);
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
function emulator_running() {
|
||||
var local_devices = shell.Exec("%comspec% /c adb devices").StdOut.ReadAll();
|
||||
if(local_devices.match(/emulator/)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function emulate() {
|
||||
// don't run emulator if a device is plugged in or if emulator is already running
|
||||
if(emulator_running()) {
|
||||
WScript.Echo("Device or Emulator already running!");
|
||||
return;
|
||||
}
|
||||
var oExec = shell.Exec("%comspec% /c android.bat list avd");
|
||||
var avd_list = [];
|
||||
var avd_id = -10;
|
||||
while(!oExec.StdOut.AtEndOfStream) {
|
||||
var output = oExec.StdOut.ReadLine();
|
||||
if(output.match(/Name: (.)*/)) {
|
||||
avd_list.push(output.replace(/ *Name:\s/, ""));
|
||||
}
|
||||
}
|
||||
// user has no AVDs
|
||||
if(avd_list.length == 0) {
|
||||
WScript.Echo("You don't have any Android Virtual Devices. Please create at least one AVD.");
|
||||
WScript.Echo("android");
|
||||
WScript.Quit(1);
|
||||
}
|
||||
// user has only one AVD so we launch that one
|
||||
if(avd_list.length == 1) {
|
||||
|
||||
shell.Run("emulator -cpu-delay 0 -no-boot-anim -cache %Temp%\cache -avd "+avd_list[0]);
|
||||
}
|
||||
|
||||
// user has more than one avd so we ask them to choose
|
||||
if(avd_list.length > 1) {
|
||||
while(!avd_list[avd_id]) {
|
||||
WScript.Echo("Choose from one of the following Android Virtual Devices [0 to "+(avd_list.length - 1)+"]:")
|
||||
for(i = 0, j = avd_list.length ; i < j ; i++) {
|
||||
WScript.Echo((i)+") "+avd_list[i]);
|
||||
}
|
||||
WScript.StdOut.Write("> ");
|
||||
avd_id = new Number(WScript.StdIn.ReadLine());
|
||||
}
|
||||
|
||||
shell.Run("emulator -cpu-delay 0 -no-boot-anim -cache %Temp%\\cache -avd "+avd_list[avd_id], 0, false);
|
||||
}
|
||||
}
|
||||
|
||||
function clean() {
|
||||
exec("%comspec% /c ant.bat clean -f "+ROOT+"\\build.xml 2>&1");
|
||||
}
|
||||
|
||||
function debug() {
|
||||
exec("%comspec% /c ant.bat debug -f "+ROOT+"\\build.xml 2>&1");
|
||||
}
|
||||
|
||||
function debug_install() {
|
||||
exec("%comspec% /c ant.bat debug install -f "+ROOT+"\\build.xml 2>&1");
|
||||
}
|
||||
|
||||
function log() {
|
||||
WScript.Echo(exec("%comspec% /c adb.bat logcat"));
|
||||
}
|
||||
|
||||
function launch() {
|
||||
var launch_str=exec("%comspec% /c java -jar "+ROOT+"\\cordova\\appinfo.jar "+ROOT+"\\AndroidManifest.xml");
|
||||
//WScript.Echo(launch_str);
|
||||
exec("%comspec% /c adb shell am start -n "+launch_str+" 2>&1");
|
||||
}
|
||||
|
||||
function BOOM() {
|
||||
clean();
|
||||
if(emulator_running()) {
|
||||
debug_install();
|
||||
launch();
|
||||
} else {
|
||||
debug();
|
||||
WScript.Echo("##################################################################");
|
||||
WScript.Echo("# Plug in your device or launch an emulator with cordova/emulate #");
|
||||
WScript.Echo("##################################################################");
|
||||
}
|
||||
}
|
||||
var args = WScript.Arguments;
|
||||
if(args.count() != 1) {
|
||||
WScript.StdErr.Write("An error has occured!\n");
|
||||
WScript.Quit(1);
|
||||
}
|
||||
eval(args(0)+"()");
|
||||
1
bin/templates/cordova/debug.bat
Normal file
1
bin/templates/cordova/debug.bat
Normal file
@@ -0,0 +1 @@
|
||||
%~dp0\cordova.bat debug
|
||||
1
bin/templates/cordova/emulate.bat
Normal file
1
bin/templates/cordova/emulate.bat
Normal file
@@ -0,0 +1 @@
|
||||
%~dp0\cordova.bat emulate
|
||||
0
bin/templates/cordova/log.bat
Normal file
0
bin/templates/cordova/log.bat
Normal file
@@ -91,8 +91,43 @@ create_project.on('exit', function(code) {
|
||||
assert(exists, 'cordova.js did not get added');
|
||||
});
|
||||
|
||||
// check that project compiles && creates a cordovaExample-debug.apk
|
||||
// XXX: !@##!@# WINDOWS
|
||||
// make sure cordova master script was added
|
||||
path.exists(util.format('%s/cordova/cordova.bat', project_path), function(exists) {
|
||||
assert(exists, 'cordova script did not get added');
|
||||
});
|
||||
|
||||
// make sure debug script was added
|
||||
path.exists(util.format('%s/cordova/debug.bat', project_path), function(exists) {
|
||||
assert(exists, 'debug script did not get added');
|
||||
});
|
||||
|
||||
// make sure BOOM script was added
|
||||
path.exists(util.format('%s/cordova/BOOM.bat', project_path), function(exists) {
|
||||
assert(exists, 'BOOM script did not get added');
|
||||
});
|
||||
|
||||
// make sure log script was added
|
||||
path.exists(util.format('%s/cordova/log.bat', project_path), function(exists) {
|
||||
assert(exists, 'log script did not get added');
|
||||
});
|
||||
|
||||
// make sure clean script was added
|
||||
path.exists(util.format('%s/cordova/clean.bat', project_path), function(exists) {
|
||||
assert(exists, 'clean script did not get added');
|
||||
});
|
||||
|
||||
// make sure emulate script was added
|
||||
path.exists(util.format('%s/cordova/emulate.bat', project_path), function(exists) {
|
||||
assert(exists, 'emulate script did not get added');
|
||||
});
|
||||
|
||||
// make sure appinfo.jar script was added
|
||||
path.exists(util.format('%s/cordova/appinfo.jar', project_path), function(exists) {
|
||||
assert(exists, 'appinfo.jar script did not get added');
|
||||
});
|
||||
|
||||
// check that project compiles && creates a cordovaExample-debug.apk
|
||||
// XXX: !@##!@# WINDOWS
|
||||
exec('ant debug -f ' + project_path + "\\build.xml", function(error, stdout, stderr) {
|
||||
assert(error == null, "Cordova Android Project does not compile");
|
||||
path.exists(util.format('%s/bin/%s-debug.apk', project_path, project_name),
|
||||
|
||||
@@ -73,10 +73,6 @@ public class App extends Plugin {
|
||||
else if (action.equals("overrideBackbutton")) {
|
||||
this.overrideBackbutton(args.getBoolean(0));
|
||||
}
|
||||
else if (action.equals("isBackbuttonOverridden")) {
|
||||
boolean b = this.isBackbuttonOverridden();
|
||||
return new PluginResult(status, b);
|
||||
}
|
||||
else if (action.equals("exitApp")) {
|
||||
this.exitApp();
|
||||
}
|
||||
@@ -188,7 +184,7 @@ public class App extends Plugin {
|
||||
*/
|
||||
public void overrideBackbutton(boolean override) {
|
||||
LOG.i("App", "WARNING: Back Button Default Behaviour will be overridden. The backbutton event will be fired!");
|
||||
this.cordova.bindBackButton(override);
|
||||
webView.bindButton(override);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -200,15 +196,7 @@ public class App extends Plugin {
|
||||
*/
|
||||
public void overrideButton(String button, boolean override) {
|
||||
LOG.i("DroidGap", "WARNING: Volume Button Default Behaviour will be overridden. The volume event will be fired!");
|
||||
this.cordova.bindButton(button, override);
|
||||
}
|
||||
/**
|
||||
* Return whether the Android back button is overridden by the user.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean isBackbuttonOverridden() {
|
||||
return this.cordova.isBackButtonBound();
|
||||
webView.bindButton(button, override);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -42,6 +42,8 @@ import android.database.Cursor;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Bitmap.CompressFormat;
|
||||
import android.media.MediaScannerConnection;
|
||||
import android.media.MediaScannerConnection.MediaScannerConnectionClient;
|
||||
import android.net.Uri;
|
||||
import android.os.Environment;
|
||||
import android.provider.MediaStore;
|
||||
@@ -52,7 +54,7 @@ import android.util.Log;
|
||||
* and returns the captured image. When the camera view is closed, the screen displayed before
|
||||
* the camera view was shown is redisplayed.
|
||||
*/
|
||||
public class CameraLauncher extends Plugin {
|
||||
public class CameraLauncher extends Plugin implements MediaScannerConnectionClient {
|
||||
|
||||
private static final int DATA_URL = 0; // Return base64 encoded string
|
||||
private static final int FILE_URI = 1; // Return file uri (content://media/external/images/media/2 for Android)
|
||||
@@ -79,9 +81,12 @@ public class CameraLauncher extends Plugin {
|
||||
private Uri imageUri; // Uri of captured image
|
||||
private int encodingType; // Type of encoding to use
|
||||
private int mediaType; // What type of media to retrieve
|
||||
private boolean saveToPhotoAlbum; // Should the picture be saved to the device's photo album
|
||||
|
||||
public String callbackId;
|
||||
private int numPics;
|
||||
|
||||
private MediaScannerConnection conn; // Used to update gallery app with newly-written files
|
||||
|
||||
//This should never be null!
|
||||
//private CordovaInterface cordova;
|
||||
@@ -117,6 +122,7 @@ public class CameraLauncher extends Plugin {
|
||||
if (action.equals("takePicture")) {
|
||||
int srcType = CAMERA;
|
||||
int destType = FILE_URI;
|
||||
this.saveToPhotoAlbum = false;
|
||||
this.targetHeight = 0;
|
||||
this.targetWidth = 0;
|
||||
this.encodingType = JPEG;
|
||||
@@ -130,6 +136,7 @@ public class CameraLauncher extends Plugin {
|
||||
this.targetHeight = args.getInt(4);
|
||||
this.encodingType = args.getInt(5);
|
||||
this.mediaType = args.getInt(6);
|
||||
this.saveToPhotoAlbum = args.getBoolean(9);
|
||||
|
||||
if (srcType == CAMERA) {
|
||||
this.takePicture(destType, encodingType);
|
||||
@@ -195,9 +202,9 @@ public class CameraLauncher extends Plugin {
|
||||
private File createCaptureFile(int encodingType) {
|
||||
File photo = null;
|
||||
if (encodingType == JPEG) {
|
||||
photo = new File(DirectoryManager.getTempDirectoryPath(this.cordova.getActivity()), "Pic.jpg");
|
||||
photo = new File(DirectoryManager.getTempDirectoryPath(this.cordova.getActivity()), ".Pic.jpg");
|
||||
} else if (encodingType == PNG) {
|
||||
photo = new File(DirectoryManager.getTempDirectoryPath(this.cordova.getActivity()), "Pic.png");
|
||||
photo = new File(DirectoryManager.getTempDirectoryPath(this.cordova.getActivity()), ".Pic.png");
|
||||
} else {
|
||||
throw new IllegalArgumentException("Invalid Encoding Type: " + encodingType);
|
||||
}
|
||||
@@ -303,7 +310,7 @@ public class CameraLauncher extends Plugin {
|
||||
ExifHelper exif = new ExifHelper();
|
||||
try {
|
||||
if (this.encodingType == JPEG) {
|
||||
exif.createInFile(DirectoryManager.getTempDirectoryPath(this.cordova.getActivity()) + "/Pic.jpg");
|
||||
exif.createInFile(DirectoryManager.getTempDirectoryPath(this.cordova.getActivity()) + "/.Pic.jpg");
|
||||
exif.readExifData();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
@@ -326,21 +333,26 @@ public class CameraLauncher extends Plugin {
|
||||
|
||||
// If sending filename back
|
||||
else if (destType == FILE_URI) {
|
||||
// Create entry in media store for image
|
||||
// (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");
|
||||
Uri uri = null;
|
||||
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.");
|
||||
Uri uri;
|
||||
if (!this.saveToPhotoAlbum) {
|
||||
uri = Uri.fromFile(new File("/data/data/" + this.cordova.getActivity().getPackageName() + "/", (new File(FileUtils.stripFileProtocol(this.imageUri.toString()))).getName()));
|
||||
} else {
|
||||
// Create entry in media store for image
|
||||
// (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 {
|
||||
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.");
|
||||
return;
|
||||
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.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -357,33 +369,37 @@ public class CameraLauncher extends Plugin {
|
||||
os.close();
|
||||
fis.close();
|
||||
|
||||
checkForDuplicateImage(FILE_URI);
|
||||
|
||||
this.success(new PluginResult(PluginResult.Status.OK, uri.toString()), this.callbackId);
|
||||
return;
|
||||
} else {
|
||||
|
||||
bitmap = scaleBitmap(getBitmapFromResult(intent));
|
||||
|
||||
// Add compressed version of captured image to returned media store Uri
|
||||
OutputStream os = this.cordova.getActivity().getContentResolver().openOutputStream(uri);
|
||||
bitmap.compress(Bitmap.CompressFormat.JPEG, this.mQuality, os);
|
||||
os.close();
|
||||
|
||||
// Restore exif data to file
|
||||
|
||||
if (this.encodingType == JPEG) {
|
||||
String exifPath;
|
||||
if (this.saveToPhotoAlbum) {
|
||||
exifPath = FileUtils.getRealPathFromURI(uri, this.cordova);
|
||||
} else {
|
||||
exifPath = uri.getPath();
|
||||
}
|
||||
exif.createOutFile(exifPath);
|
||||
exif.writeExifData();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bitmap = scaleBitmap(getBitmapFromResult(intent));
|
||||
|
||||
// Add compressed version of captured image to returned media store Uri
|
||||
OutputStream os = this.cordova.getActivity().getContentResolver().openOutputStream(uri);
|
||||
bitmap.compress(Bitmap.CompressFormat.JPEG, this.mQuality, os);
|
||||
os.close();
|
||||
|
||||
// Restore exif data to file
|
||||
if (this.encodingType == JPEG) {
|
||||
exif.createOutFile(FileUtils.getRealPathFromURI(uri, this.cordova));
|
||||
exif.writeExifData();
|
||||
}
|
||||
|
||||
// Send Uri back to JavaScript for viewing image
|
||||
this.success(new PluginResult(PluginResult.Status.OK, uri.toString()), this.callbackId);
|
||||
}
|
||||
bitmap.recycle();
|
||||
|
||||
this.cleanup(FILE_URI, this.imageUri, bitmap);
|
||||
bitmap = null;
|
||||
System.gc();
|
||||
|
||||
checkForDuplicateImage(FILE_URI);
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
this.failPicture("Error capturing image.");
|
||||
@@ -514,6 +530,22 @@ public class CameraLauncher extends Plugin {
|
||||
null,
|
||||
null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans up after picture taking. Checking for duplicates and that kind of stuff.
|
||||
*/
|
||||
private void cleanup(int imageType, Uri oldImage, Bitmap bitmap) {
|
||||
bitmap.recycle();
|
||||
|
||||
// Clean up initial camera-written image file.
|
||||
(new File(FileUtils.stripFileProtocol(oldImage.toString()))).delete();
|
||||
|
||||
checkForDuplicateImage(imageType);
|
||||
// Scan for the gallery to update pic refs in gallery
|
||||
this.scanForGallery();
|
||||
|
||||
System.gc();
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to find out if we are in a situation where the Camera Intent adds to images
|
||||
@@ -584,4 +616,24 @@ public class CameraLauncher extends Plugin {
|
||||
public void failPicture(String err) {
|
||||
this.error(new PluginResult(PluginResult.Status.ERROR, err), this.callbackId);
|
||||
}
|
||||
|
||||
private void scanForGallery() {
|
||||
if(this.conn!=null) this.conn.disconnect();
|
||||
this.conn = new MediaScannerConnection(this.ctx.getActivity().getApplicationContext(), this);
|
||||
conn.connect();
|
||||
}
|
||||
|
||||
public void onMediaScannerConnected() {
|
||||
try{
|
||||
this.conn.scanFile(this.imageUri.toString(), "image/*");
|
||||
} catch (java.lang.IllegalStateException e){
|
||||
e.printStackTrace();
|
||||
LOG.d(LOG_TAG, "Can;t scan file in MediaScanner aftering taking picture");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void onScanCompleted(String path, Uri uri) {
|
||||
this.conn.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.WindowManager;
|
||||
import android.webkit.WebSettings;
|
||||
import android.webkit.WebView;
|
||||
@@ -51,8 +52,12 @@ public class CordovaWebView extends WebView {
|
||||
/** The whitelist **/
|
||||
private ArrayList<Pattern> whiteList = new ArrayList<Pattern>();
|
||||
private HashMap<String, Boolean> whiteListCache = new HashMap<String, Boolean>();
|
||||
private ArrayList<Integer> keyDownCodes = new ArrayList<Integer>();
|
||||
private ArrayList<Integer> keyUpCodes = new ArrayList<Integer>();
|
||||
|
||||
public PluginManager pluginManager;
|
||||
public CallbackServer callbackServer;
|
||||
|
||||
|
||||
/** Actvities and other important classes **/
|
||||
private CordovaInterface cordova;
|
||||
@@ -70,6 +75,12 @@ public class CordovaWebView extends WebView {
|
||||
// Flag to track that a loadUrl timeout occurred
|
||||
int loadUrlTimeout = 0;
|
||||
|
||||
private boolean bound;
|
||||
|
||||
private boolean volumedownBound;
|
||||
|
||||
private boolean volumeupBound;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
@@ -660,4 +671,104 @@ public class CordovaWebView extends WebView {
|
||||
}
|
||||
return p.toString();
|
||||
}
|
||||
|
||||
/*
|
||||
* onKeyDown
|
||||
*/
|
||||
|
||||
@Override
|
||||
public boolean onKeyDown(int keyCode, KeyEvent event)
|
||||
{
|
||||
if(keyDownCodes.contains(keyCode))
|
||||
{
|
||||
if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
|
||||
// only override default behaviour is event bound
|
||||
LOG.d(TAG, "Down Key Hit");
|
||||
this.loadUrl("javascript:cordova.fireDocumentEvent('volumedownbutton');");
|
||||
return true;
|
||||
}
|
||||
// If volumeup key
|
||||
else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
|
||||
LOG.d(TAG, "Up Key Hit");
|
||||
this.loadUrl("javascript:cordova.fireDocumentEvent('volumeupbutton');");
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Do some other stuff!
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyUp(int keyCode, KeyEvent event)
|
||||
{
|
||||
|
||||
Log.d(TAG, "KeyDown has been triggered on the view");
|
||||
|
||||
// If back key
|
||||
if (keyCode == KeyEvent.KEYCODE_BACK) {
|
||||
// If back key is bound, then send event to JavaScript
|
||||
if (this.bound) {
|
||||
this.loadUrl("javascript:cordova.fireDocumentEvent('backbutton');");
|
||||
return true;
|
||||
} else {
|
||||
// If not bound
|
||||
// Go to previous page in webview if it is possible to go back
|
||||
if (this.backHistory()) {
|
||||
return true;
|
||||
}
|
||||
// If not, then invoke default behaviour
|
||||
else {
|
||||
//this.activityState = ACTIVITY_EXITING;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Legacy
|
||||
else if (keyCode == KeyEvent.KEYCODE_MENU) {
|
||||
this.loadUrl("javascript:cordova.fireDocumentEvent('menubutton');");
|
||||
return super.onKeyUp(keyCode, event);
|
||||
}
|
||||
// If search key
|
||||
else if (keyCode == KeyEvent.KEYCODE_SEARCH) {
|
||||
this.loadUrl("javascript:cordova.fireDocumentEvent('searchbutton');");
|
||||
return true;
|
||||
}
|
||||
else if(keyUpCodes.contains(keyCode))
|
||||
{
|
||||
//What the hell should this do?
|
||||
}
|
||||
|
||||
|
||||
Log.d(TAG, "KeyUp has been triggered on the view");
|
||||
return false;
|
||||
}
|
||||
|
||||
public void bindButton(boolean override)
|
||||
{
|
||||
this.bound = override;
|
||||
}
|
||||
|
||||
public void bindButton(String button, boolean override) {
|
||||
// TODO Auto-generated method stub
|
||||
if (button.compareTo("volumeup")==0) {
|
||||
keyDownCodes.add(KeyEvent.KEYCODE_VOLUME_UP);
|
||||
}
|
||||
else if (button.compareTo("volumedown")==0) {
|
||||
keyDownCodes.add(KeyEvent.KEYCODE_VOLUME_DOWN);
|
||||
}
|
||||
}
|
||||
|
||||
public void bindButton(int keyCode, boolean keyDown, boolean override) {
|
||||
if(keyDown)
|
||||
{
|
||||
keyDownCodes.add(keyCode);
|
||||
}
|
||||
else
|
||||
{
|
||||
keyUpCodes.add(keyCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,20 +21,26 @@ package org.apache.cordova;
|
||||
import java.util.Hashtable;
|
||||
|
||||
import org.apache.cordova.api.CordovaInterface;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.apache.cordova.api.LOG;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.content.res.AssetManager;
|
||||
import android.graphics.Bitmap;
|
||||
import android.net.Uri;
|
||||
import android.net.http.SslError;
|
||||
import android.view.View;
|
||||
import android.webkit.HttpAuthHandler;
|
||||
import android.webkit.SslErrorHandler;
|
||||
import android.webkit.WebResourceResponse;
|
||||
import android.webkit.WebView;
|
||||
import android.webkit.WebViewClient;
|
||||
|
||||
@@ -241,6 +247,7 @@ public class CordovaWebViewClient extends WebViewClient {
|
||||
* Notify the host application that a page has finished loading.
|
||||
* This method is called only for main frame. When onPageFinished() is called, the rendering picture may not be updated yet.
|
||||
*
|
||||
*
|
||||
* @param view The webview initiating the callback.
|
||||
* @param url The url of the page.
|
||||
*/
|
||||
@@ -344,6 +351,7 @@ public class CordovaWebViewClient extends WebViewClient {
|
||||
|
||||
final String packageName = this.cordova.getActivity().getPackageName();
|
||||
final PackageManager pm = this.cordova.getActivity().getPackageManager();
|
||||
|
||||
ApplicationInfo appInfo;
|
||||
try {
|
||||
appInfo = pm.getApplicationInfo(packageName, PackageManager.GET_META_DATA);
|
||||
@@ -451,4 +459,43 @@ public class CordovaWebViewClient extends WebViewClient {
|
||||
this.authenticationTokens.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
|
||||
if(url.contains("?") || url.contains("#")){
|
||||
return generateWebResourceResponse(url);
|
||||
} else {
|
||||
return super.shouldInterceptRequest(view, url);
|
||||
}
|
||||
}
|
||||
|
||||
private WebResourceResponse generateWebResourceResponse(String url) {
|
||||
final String ANDROID_ASSET = "file:///android_asset/";
|
||||
if (url.startsWith(ANDROID_ASSET)) {
|
||||
String niceUrl = url;
|
||||
niceUrl = url.replaceFirst(ANDROID_ASSET, "");
|
||||
if(niceUrl.contains("?")){
|
||||
niceUrl = niceUrl.split("\\?")[0];
|
||||
}
|
||||
else if(niceUrl.contains("#"))
|
||||
{
|
||||
niceUrl = niceUrl.split("#")[0];
|
||||
}
|
||||
|
||||
String mimetype = null;
|
||||
if(niceUrl.endsWith(".html")){
|
||||
mimetype = "text/html";
|
||||
}
|
||||
|
||||
try {
|
||||
AssetManager assets = cordova.getActivity().getAssets();
|
||||
Uri uri = Uri.parse(niceUrl);
|
||||
InputStream stream = assets.open(uri.getPath(), AssetManager.ACCESS_STREAMING);
|
||||
WebResourceResponse response = new WebResourceResponse(mimetype, "UTF-8", stream);
|
||||
return response;
|
||||
} catch (IOException e) {
|
||||
LOG.e("generateWebResourceResponse", e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,7 +138,6 @@ public class DroidGap extends Activity implements CordovaInterface {
|
||||
protected CordovaWebViewClient webViewClient;
|
||||
|
||||
protected LinearLayout root;
|
||||
public boolean bound = false;
|
||||
protected boolean cancelLoadUrl = false;
|
||||
protected ProgressDialog spinnerDialog = null;
|
||||
|
||||
@@ -181,10 +180,6 @@ public class DroidGap extends Activity implements CordovaInterface {
|
||||
// when another application (activity) is started.
|
||||
protected boolean keepRunning = true;
|
||||
|
||||
private boolean volumeupBound;
|
||||
|
||||
private boolean volumedownBound;
|
||||
|
||||
/**
|
||||
* Sets the authentication token.
|
||||
*
|
||||
@@ -784,87 +779,7 @@ public class DroidGap extends Activity implements CordovaInterface {
|
||||
super.finish();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a key is released. (Key UP)
|
||||
*
|
||||
* @param keyCode
|
||||
* @param event
|
||||
*/
|
||||
@Override
|
||||
public boolean onKeyUp(int keyCode, KeyEvent event) {
|
||||
if (this.appView == null) {
|
||||
return super.onKeyUp(keyCode, event);
|
||||
}
|
||||
|
||||
// If back key
|
||||
if (keyCode == KeyEvent.KEYCODE_BACK) {
|
||||
// If back key is bound, then send event to JavaScript
|
||||
if (this.bound) {
|
||||
this.appView.loadUrl("javascript:cordova.fireDocumentEvent('backbutton');");
|
||||
return true;
|
||||
} else {
|
||||
// If not bound
|
||||
// Go to previous page in webview if it is possible to go back
|
||||
if (this.backHistory()) {
|
||||
return true;
|
||||
}
|
||||
// If not, then invoke behavior of super class
|
||||
else {
|
||||
this.activityState = ACTIVITY_EXITING;
|
||||
return super.onKeyUp(keyCode, event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If menu key
|
||||
else if (keyCode == KeyEvent.KEYCODE_MENU) {
|
||||
this.appView.loadUrl("javascript:cordova.fireDocumentEvent('menubutton');");
|
||||
return super.onKeyUp(keyCode, event);
|
||||
}
|
||||
|
||||
// If search key
|
||||
else if (keyCode == KeyEvent.KEYCODE_SEARCH) {
|
||||
this.appView.loadUrl("javascript:cordova.fireDocumentEvent('searchbutton');");
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a key is pressed. (Key DOWN)
|
||||
*
|
||||
* @param keyCode
|
||||
* @param event
|
||||
*/
|
||||
@Override
|
||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||
if (this.appView == null) {
|
||||
return super.onKeyDown(keyCode, event);
|
||||
}
|
||||
|
||||
// If volumedown key
|
||||
if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
|
||||
if (this.volumedownBound==true) {
|
||||
// only override default behaviour is event bound
|
||||
LOG.d(TAG, "Down Key Hit");
|
||||
this.appView.loadUrl("javascript:cordova.fireDocumentEvent('volumedownbutton');");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// If volumeup key
|
||||
else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
|
||||
if (this.volumeupBound==true) {
|
||||
// only override default behaviour is event bound
|
||||
LOG.d(TAG, "Up Key Hit");
|
||||
this.appView.loadUrl("javascript:cordova.fireDocumentEvent('volumeupbutton');");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return super.onKeyDown(keyCode, event);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Launch an activity for which you would like a result when it finished. When this activity exits,
|
||||
* your onActivityResult() method will be called.
|
||||
@@ -1028,24 +943,6 @@ public class DroidGap extends Activity implements CordovaInterface {
|
||||
return this.getContext();
|
||||
}
|
||||
|
||||
/**
|
||||
* Override the backbutton.
|
||||
*
|
||||
* @param override
|
||||
*/
|
||||
public void bindBackButton(boolean override) {
|
||||
this.bound = override;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine of backbutton is overridden.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isBackButtonBound() {
|
||||
return this.bound;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the specified URL in the Cordova webview or a new browser instance.
|
||||
*
|
||||
@@ -1062,16 +959,6 @@ public class DroidGap extends Activity implements CordovaInterface {
|
||||
}
|
||||
}
|
||||
|
||||
public void bindButton(String button, boolean override) {
|
||||
// TODO Auto-generated method stub
|
||||
if (button.compareTo("volumeup")==0) {
|
||||
this.volumeupBound = override;
|
||||
}
|
||||
else if (button.compareTo("volumedown")==0) {
|
||||
this.volumedownBound = override;
|
||||
}
|
||||
}
|
||||
|
||||
protected Dialog splashDialog;
|
||||
|
||||
/**
|
||||
|
||||
@@ -44,19 +44,6 @@ public interface CordovaInterface {
|
||||
*/
|
||||
abstract public void setActivityResultCallback(IPlugin plugin);
|
||||
|
||||
/**
|
||||
* Causes the Activity to override the back button behavior.
|
||||
*
|
||||
* @param override
|
||||
*/
|
||||
public abstract void bindBackButton(boolean override);
|
||||
|
||||
/**
|
||||
* A hook required to check if the Back Button is bound.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public abstract boolean isBackButtonBound();
|
||||
|
||||
/**
|
||||
* Get the Android activity.
|
||||
@@ -77,5 +64,4 @@ public interface CordovaInterface {
|
||||
*/
|
||||
public Object onMessage(String id, Object data);
|
||||
|
||||
public abstract void bindButton(String button, boolean override);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user