Skip to content
Browse files

Added Foreground Camera Plugin and Foreground Gallery Plugin for Phon…

…egap (Cordova) 2.1.0.
  • Loading branch information...
1 parent beff916 commit adb560387fe1f12faa8da4b1218409e1e3a8db85 Vinícius Soares Fonseca committed Oct 3, 2012
Showing with 16,398 additions and 0 deletions.
  1. +136 −0 Android/ForegroundCamera/CameraActivity.java
  2. +380 −0 Android/ForegroundCamera/ForegroundCameraLauncher.java
  3. +73 −0 Android/ForegroundCamera/ForegroundCameraPreview.java
  4. +202 −0 Android/ForegroundCamera/LICENSE
  5. +9 −0 Android/ForegroundCamera/NOTICE
  6. +43 −0 Android/ForegroundCamera/README.txt
  7. +9 −0 Android/ForegroundCamera/Sample/ForegroundCameraPlugin/.classpath
  8. +33 −0 Android/ForegroundCamera/Sample/ForegroundCameraPlugin/.project
  9. +61 −0 Android/ForegroundCamera/Sample/ForegroundCameraPlugin/AndroidManifest.xml
  10. +202 −0 Android/ForegroundCamera/Sample/ForegroundCameraPlugin/LICENSE
  11. +9 −0 Android/ForegroundCamera/Sample/ForegroundCameraPlugin/NOTICE
  12. +49 −0 Android/ForegroundCamera/Sample/ForegroundCameraPlugin/README.txt
  13. +83 −0 Android/ForegroundCamera/Sample/ForegroundCameraPlugin/assets/www/index.html
  14. +91 −0 Android/ForegroundCamera/Sample/ForegroundCameraPlugin/assets/www/js/camera.js
  15. +5,814 −0 Android/ForegroundCamera/Sample/ForegroundCameraPlugin/assets/www/js/cordova-2.1.0.js
  16. BIN Android/ForegroundCamera/Sample/ForegroundCameraPlugin/libs/cordova-2.1.0.jar
  17. +11 −0 Android/ForegroundCamera/Sample/ForegroundCameraPlugin/project.properties
  18. BIN Android/ForegroundCamera/Sample/ForegroundCameraPlugin/res/drawable-hdpi/ic_launcher.png
  19. BIN Android/ForegroundCamera/Sample/ForegroundCameraPlugin/res/drawable-ldpi/ic_launcher.png
  20. BIN Android/ForegroundCamera/Sample/ForegroundCameraPlugin/res/drawable-mdpi/ic_launcher.png
  21. +48 −0 Android/ForegroundCamera/Sample/ForegroundCameraPlugin/res/layout/foregroundcameraplugin.xml
  22. +22 −0 Android/ForegroundCamera/Sample/ForegroundCameraPlugin/res/values/strings.xml
  23. +58 −0 Android/ForegroundCamera/Sample/ForegroundCameraPlugin/res/xml/config.xml
  24. +33 −0 Android/ForegroundCamera/Sample/ForegroundCameraPlugin/src/com/foregroundcameraplugin/App.java
  25. +136 −0 ...ForegroundCamera/Sample/ForegroundCameraPlugin/src/com/foregroundcameraplugin/CameraActivity.java
  26. +380 −0 ...Camera/Sample/ForegroundCameraPlugin/src/com/foregroundcameraplugin/ForegroundCameraLauncher.java
  27. +73 −0 ...dCamera/Sample/ForegroundCameraPlugin/src/com/foregroundcameraplugin/ForegroundCameraPreview.java
  28. +91 −0 Android/ForegroundCamera/camera.js
  29. +48 −0 Android/ForegroundCamera/foregroundcameraplugin.xml
  30. +83 −0 Android/ForegroundCamera/index.html
  31. +22 −0 Android/ForegroundCamera/strings.xml
  32. +136 −0 Android/ForegroundGallery/CameraActivity.java
  33. +380 −0 Android/ForegroundGallery/ForegroundCameraLauncher.java
  34. +73 −0 Android/ForegroundGallery/ForegroundCameraPreview.java
  35. +202 −0 Android/ForegroundGallery/LICENSE
  36. +9 −0 Android/ForegroundGallery/NOTICE
  37. +43 −0 Android/ForegroundGallery/README.txt
  38. +9 −0 Android/ForegroundGallery/Sample/ForegroundCameraPlugin/.classpath
  39. +33 −0 Android/ForegroundGallery/Sample/ForegroundCameraPlugin/.project
  40. +61 −0 Android/ForegroundGallery/Sample/ForegroundCameraPlugin/AndroidManifest.xml
  41. +202 −0 Android/ForegroundGallery/Sample/ForegroundCameraPlugin/LICENSE
  42. +9 −0 Android/ForegroundGallery/Sample/ForegroundCameraPlugin/NOTICE
  43. +49 −0 Android/ForegroundGallery/Sample/ForegroundCameraPlugin/README.txt
  44. +83 −0 Android/ForegroundGallery/Sample/ForegroundCameraPlugin/assets/www/index.html
  45. +91 −0 Android/ForegroundGallery/Sample/ForegroundCameraPlugin/assets/www/js/camera.js
  46. +5,814 −0 Android/ForegroundGallery/Sample/ForegroundCameraPlugin/assets/www/js/cordova-2.1.0.js
  47. BIN Android/ForegroundGallery/Sample/ForegroundCameraPlugin/libs/cordova-2.1.0.jar
  48. +11 −0 Android/ForegroundGallery/Sample/ForegroundCameraPlugin/project.properties
  49. BIN Android/ForegroundGallery/Sample/ForegroundCameraPlugin/res/drawable-hdpi/ic_launcher.png
  50. BIN Android/ForegroundGallery/Sample/ForegroundCameraPlugin/res/drawable-ldpi/ic_launcher.png
  51. BIN Android/ForegroundGallery/Sample/ForegroundCameraPlugin/res/drawable-mdpi/ic_launcher.png
  52. +48 −0 Android/ForegroundGallery/Sample/ForegroundCameraPlugin/res/layout/foregroundcameraplugin.xml
  53. +22 −0 Android/ForegroundGallery/Sample/ForegroundCameraPlugin/res/values/strings.xml
  54. +58 −0 Android/ForegroundGallery/Sample/ForegroundCameraPlugin/res/xml/config.xml
  55. +33 −0 Android/ForegroundGallery/Sample/ForegroundCameraPlugin/src/com/foregroundcameraplugin/App.java
  56. +136 −0 ...oregroundGallery/Sample/ForegroundCameraPlugin/src/com/foregroundcameraplugin/CameraActivity.java
  57. +380 −0 ...allery/Sample/ForegroundCameraPlugin/src/com/foregroundcameraplugin/ForegroundCameraLauncher.java
  58. +73 −0 ...Gallery/Sample/ForegroundCameraPlugin/src/com/foregroundcameraplugin/ForegroundCameraPreview.java
  59. +91 −0 Android/ForegroundGallery/camera.js
  60. +48 −0 Android/ForegroundGallery/foregroundcameraplugin.xml
  61. +83 −0 Android/ForegroundGallery/index.html
  62. +22 −0 Android/ForegroundGallery/strings.xml
View
136 Android/ForegroundCamera/CameraActivity.java
@@ -0,0 +1,136 @@
+/*
+ Copyright 2012 Bruno Carreira - Lucas Farias - Rafael Luna - Vinícius Fonseca.
+
+ Licensed 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 com.foregroundcameraplugin;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import android.app.Activity;
+import android.hardware.Camera;
+import android.hardware.Camera.AutoFocusCallback;
+import android.hardware.Camera.PictureCallback;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.MediaStore;
+import android.util.Log;
+import android.view.View;
+import android.widget.Button;
+import android.widget.FrameLayout;
+
+/**
+ * Camera Activity Class. Configures Android camera to take picture and show it.
+ */
+public class CameraActivity extends Activity {
+
+ private static final String TAG = "CameraActivity";
+
+ private Camera mCamera;
+ private ForegroundCameraPreview mPreview;
+ private boolean pressed = false;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.foregroundcameraplugin);
+
+ // Create an instance of Camera
+ mCamera = getCameraInstance();
+
+ // Create a Preview and set it as the content of activity.
+ mPreview = new ForegroundCameraPreview(this, mCamera);
+ FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
+ preview.addView(mPreview);
+
+ // Add a listener to the Capture button
+ Button captureButton = (Button) findViewById(R.id.button_capture);
+ captureButton.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+
+ if (pressed)
+ return;
+
+ // Set pressed = true to prevent freezing.
+ // Issue 1 at
+ // http://code.google.com/p/foreground-camera-plugin/issues/detail?id=1
+ pressed = true;
+
+ // get an image from the camera
+ mCamera.autoFocus(new AutoFocusCallback() {
+
+ public void onAutoFocus(boolean success, Camera camera) {
+ mCamera.takePicture(null, null, mPicture);
+ }
+ });
+ }
+ });
+
+ Button cancelButton = (Button) findViewById(R.id.button_cancel);
+ cancelButton.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ pressed = false;
+ setResult(RESULT_CANCELED);
+ finish();
+ }
+ });
+ }
+
+ @Override
+ protected void onPause() {
+ if (mCamera != null) {
+ mCamera.release(); // release the camera for other applications
+ mCamera = null;
+ }
+ super.onPause();
+ }
+
+ /** A safe way to get an instance of the Camera object. */
+ public static Camera getCameraInstance() {
+ Camera c = null;
+ try {
+ c = Camera.open(); // attempt to get a Camera instance
+ } catch (Exception e) {
+ // Camera is not available (in use or does not exist)
+ }
+ return c; // returns null if camera is unavailable
+ }
+
+ private PictureCallback mPicture = new PictureCallback() {
+
+ public void onPictureTaken(byte[] data, Camera camera) {
+
+ Uri fileUri = (Uri) getIntent().getExtras().get(
+ MediaStore.EXTRA_OUTPUT);
+
+ File pictureFile = new File(fileUri.getPath());
+
+ try {
+ FileOutputStream fos = new FileOutputStream(pictureFile);
+ fos.write(data);
+ fos.close();
+ } catch (FileNotFoundException e) {
+ Log.d(TAG, "File not found: " + e.getMessage());
+ } catch (IOException e) {
+ Log.d(TAG, "Error accessing file: " + e.getMessage());
+ }
+ setResult(RESULT_OK);
+ pressed = false;
+ finish();
+ }
+ };
+}
View
380 Android/ForegroundCamera/ForegroundCameraLauncher.java
@@ -0,0 +1,380 @@
+/*
+ Copyright 2012 Bruno Carreira - Lucas Farias - Rafael Luna - Vin�cius Fonseca.
+
+ Licensed 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 com.foregroundcameraplugin;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.apache.cordova.CameraLauncher;
+import org.apache.cordova.ExifHelper;
+import org.apache.cordova.api.CordovaInterface;
+import org.apache.cordova.api.LOG;
+import org.apache.cordova.api.Plugin;
+import org.apache.cordova.api.PluginResult;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import android.app.Activity;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.Intent;
+import android.database.Cursor;
+import android.graphics.Bitmap;
+import android.net.Uri;
+import android.os.Environment;
+import android.provider.MediaStore;
+
+/**
+ * This class launches the camera view, allows the user to take a picture,
+ * closes the camera view, and returns the captured image. When the camera view
+ * is closed, the screen displayed before the camera view was shown is
+ * redisplayed.
+ */
+public class ForegroundCameraLauncher extends CameraLauncher {
+
+ private static final String LOG_TAG = "ForegroundCameraLauncher";
+
+ private int mQuality;
+ private int targetWidth;
+ private int targetHeight;
+
+ private Uri imageUri;
+ private File photo;
+
+ public String callbackId;
+ private int numPics;
+
+ private static final String _DATA = "_data";
+
+ /**
+ * Constructor.
+ */
+ public ForegroundCameraLauncher() {
+ }
+
+ /**
+ * Executes the request and returns PluginResult.
+ *
+ * @param action
+ * The action to execute.
+ * @param args
+ * JSONArry of arguments for the plugin.
+ * @param callbackId
+ * The callback id used when calling back into JavaScript.
+ * @return A PluginResult object with a status and message.
+ */
+ public PluginResult execute(String action, JSONArray args, String callbackId) {
+ PluginResult.Status status = PluginResult.Status.OK;
+ String result = "";
+ this.callbackId = callbackId;
+
+ try {
+ if (action.equals("takePicture")) {
+ this.targetHeight = 0;
+ this.targetWidth = 0;
+ this.mQuality = 80;
+
+ JSONObject options = args.optJSONObject(0);
+ if (options != null) {
+ this.targetHeight = options.getInt("targetHeight");
+ this.targetWidth = options.getInt("targetWidth");
+ this.mQuality = options.getInt("quality");
+ }
+
+ this.takePicture();
+
+ PluginResult r = new PluginResult(PluginResult.Status.NO_RESULT);
+ r.setKeepCallback(true);
+ return r;
+ }
+ return new PluginResult(status, result);
+ } catch (JSONException e) {
+ e.printStackTrace();
+ return new PluginResult(PluginResult.Status.JSON_EXCEPTION);
+ }
+ }
+
+ // --------------------------------------------------------------------------
+ // LOCAL METHODS
+ // --------------------------------------------------------------------------
+
+ /**
+ * Take a picture with the camera. When an image is captured or the camera
+ * view is cancelled, the result is returned in
+ * CordovaActivity.onActivityResult, which forwards the result to
+ * this.onActivityResult.
+ *
+ * The image can either be returned as a base64 string or a URI that points
+ * to the file. To display base64 string in an img tag, set the source to:
+ * img.src="data:image/jpeg;base64,"+result; or to display URI in an img tag
+ * img.src=result;
+ *
+ */
+ public void takePicture() {
+ // Save the number of images currently on disk for later
+ this.numPics = queryImgDB().getCount();
+
+ Intent intent = new Intent(this.cordova.getActivity().getApplicationContext(), CameraActivity.class);
+ this.photo = createCaptureFile();
+ this.imageUri = Uri.fromFile(photo);
+ intent.putExtra(MediaStore.EXTRA_OUTPUT, this.imageUri);
+
+ this.cordova.startActivityForResult((Plugin) this, intent, 1);
+ }
+
+ /**
+ * Create a file in the applications temporary directory based upon the
+ * supplied encoding.
+ *
+ * @return a File object pointing to the temporary picture
+ */
+ private File createCaptureFile() {
+ File photo = new File(getTempDirectoryPath(this.cordova.getActivity().getApplicationContext()), "Pic.jpg");
+ return photo;
+ }
+
+ /**
+ * Called when the camera view exits.
+ *
+ * @param requestCode
+ * The request code originally supplied to
+ * startActivityForResult(), allowing you to identify who this
+ * result came from.
+ * @param resultCode
+ * The integer result code returned by the child activity through
+ * its setResult().
+ * @param intent
+ * An Intent, which can return result data to the caller (various
+ * data can be attached to Intent "extras").
+ */
+ public void onActivityResult(int requestCode, int resultCode, Intent intent) {
+
+ // If image available
+ if (resultCode == Activity.RESULT_OK) {
+ try {
+ // Create an ExifHelper to save the exif data that is lost
+ // during compression
+ ExifHelper exif = new ExifHelper();
+ exif.createInFile(getTempDirectoryPath(this.cordova.getActivity().getApplicationContext())
+ + "/Pic.jpg");
+ exif.readExifData();
+
+ // Read in bitmap of captured image
+ Bitmap bitmap;
+ try {
+ bitmap = android.provider.MediaStore.Images.Media
+ .getBitmap(this.cordova.getActivity().getContentResolver(), imageUri);
+ } catch (FileNotFoundException e) {
+ Uri uri = intent.getData();
+ android.content.ContentResolver resolver = this.cordova.getActivity().getContentResolver();
+ bitmap = android.graphics.BitmapFactory
+ .decodeStream(resolver.openInputStream(uri));
+ }
+
+ bitmap = scaleBitmap(bitmap);
+
+ // 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.");
+ 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;
+ }
+ }
+
+ // 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
+ exif.createOutFile(getRealPathFromURI(uri, this.ctx));
+ exif.writeExifData();
+
+ // Send Uri back to JavaScript for viewing image
+ this.success(new PluginResult(PluginResult.Status.OK,
+ getRealPathFromURI(uri, this.ctx)), this.callbackId);
+
+ bitmap.recycle();
+ bitmap = null;
+ System.gc();
+
+ checkForDuplicateImage();
+ } catch (IOException e) {
+ e.printStackTrace();
+ this.failPicture("Error capturing image.");
+ }
+ }
+
+ // If cancelled
+ else if (resultCode == Activity.RESULT_CANCELED) {
+ this.failPicture("Camera cancelled.");
+ }
+
+ // If something else
+ else {
+ this.failPicture("Did not complete!");
+ }
+ }
+
+ /**
+ * 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;
+ }
+ }
+
+ return Bitmap.createScaledBitmap(bitmap, newWidth, newHeight, true);
+ }
+
+ /**
+ * Creates a cursor that can be used to determine how many images we have.
+ *
+ * @return a cursor
+ */
+ private Cursor queryImgDB() {
+ return this.cordova.getActivity().getContentResolver().query(
+ android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
+ new String[] { MediaStore.Images.Media._ID }, null, null, null);
+ }
+
+ /**
+ * Used to find out if we are in a situation where the Camera Intent adds to
+ * images to the content store. If we are using a FILE_URI and the number of
+ * images in the DB increases by 2 we have a duplicate, when using a
+ * DATA_URL the number is 1.
+ */
+ private void checkForDuplicateImage() {
+ int diff = 2;
+ Cursor cursor = queryImgDB();
+ int currentNumOfImages = cursor.getCount();
+
+ // delete the duplicate file if the difference is 2 for file URI or 1
+ // for Data URL
+ if ((currentNumOfImages - numPics) == diff) {
+ cursor.moveToLast();
+ int id = Integer.valueOf(cursor.getString(cursor
+ .getColumnIndex(MediaStore.Images.Media._ID))) - 1;
+ Uri uri = Uri.parse(MediaStore.Images.Media.EXTERNAL_CONTENT_URI
+ + "/" + id);
+ this.cordova.getActivity().getContentResolver().delete(uri, null, null);
+ }
+ }
+
+ /**
+ * Determine if we can use the SD Card to store the temporary file. If not
+ * then use the internal cache directory.
+ *
+ * @return the absolute path of where to store the file
+ */
+ private String getTempDirectoryPath(Context ctx) {
+ File cache = null;
+
+ // SD Card Mounted
+ if (Environment.getExternalStorageState().equals(
+ Environment.MEDIA_MOUNTED)) {
+ cache = new File(Environment.getExternalStorageDirectory()
+ .getAbsolutePath()
+ + "/Android/data/"
+ + ctx.getPackageName() + "/cache/");
+ }
+ // Use internal storage
+ else {
+ cache = ctx.getCacheDir();
+ }
+
+ // Create the cache directory if it doesn't exist
+ if (!cache.exists()) {
+ cache.mkdirs();
+ }
+
+ return cache.getAbsolutePath();
+ }
+
+ /**
+ * 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 ctx
+ * the current applicaiton context
+ * @return the full path to the file
+ */
+ private String getRealPathFromURI(Uri contentUri, CordovaInterface ctx) {
+ 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);
+ }
+}
View
73 Android/ForegroundCamera/ForegroundCameraPreview.java
@@ -0,0 +1,73 @@
+/*
+ Copyright 2012 Bruno Carreira - Lucas Farias - Rafael Luna - Vinícius Fonseca.
+
+ Licensed 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 com.foregroundcameraplugin;
+
+import java.io.IOException;
+
+import android.content.Context;
+import android.hardware.Camera;
+import android.util.Log;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+
+public class ForegroundCameraPreview extends SurfaceView implements SurfaceHolder.Callback {
+ private SurfaceHolder mHolder;
+ private Camera mCamera;
+ private static final String TAG = "CameraPreview";
+
+ public ForegroundCameraPreview(Context context, Camera camera) {
+ super(context);
+ mCamera = camera;
+
+ mHolder = getHolder();
+ mHolder.addCallback(this);
+ mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
+ }
+
+ public void surfaceCreated(SurfaceHolder holder) {
+ try {
+ mCamera.setPreviewDisplay(holder);
+ mCamera.startPreview();
+ } catch (IOException e) {
+ Log.d(TAG, "Error setting camera preview: " + e.getMessage());
+ }
+ }
+
+ public void surfaceDestroyed(SurfaceHolder holder) {
+ }
+
+
+ public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
+
+ if (mHolder.getSurface() == null){
+ return;
+ }
+
+ try {
+ mCamera.stopPreview();
+ } catch (Exception e){
+ }
+
+ try {
+ mCamera.setPreviewDisplay(mHolder);
+ mCamera.startPreview();
+
+ } catch (Exception e){
+ Log.d(TAG, "Error starting camera preview: " + e.getMessage());
+ }
+ }
+}
View
202 Android/ForegroundCamera/LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed 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.
View
9 Android/ForegroundCamera/NOTICE
@@ -0,0 +1,9 @@
+Foreground Camera Plugin for Phonegap (Cordova)
+Copyright 2012 Bruno Carreira - Lucas Farias - Rafael Luna - Vin�cius Fonseca.
+
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org)
+
+- src/com/foregroundcameraplugin/ForegroundCameraLauncher.java was based on CameraLauncher.java, found in Phonegap (Apache Cordova) version 1.8.0.
+- assets/www/js/camera.js was based on cordova-1.8.0.js, found in Phonegap (Apache Cordova) version 1.8.0.
+- res/xml/plugins.xml was adapted from plugins.xml, found in Phonegap (Apache Cordova) version 1.8.0.
View
43 Android/ForegroundCamera/README.txt
@@ -0,0 +1,43 @@
+ Copyright 2012 Bruno Carreira - Lucas Farias - Rafael Luna - Vin�cius Fonseca.
+
+ Licensed 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.
+
+Foreground Camera Plugin for Phonegap (Cordova).
+
+Originally by: - Bruno Carreira
+ - Lucas Farias
+ - Rafael Luna
+ - Vinicius Fonseca
+
+The default Phonegap (Cordova) Camera Plugin calls the native camera and this makes Android Garbage Collector to kill background applications. This plugin avoid your application to go background and be killed by Garbage Collector with other applications. We used the Phonegap source code and modified it to avoid this problem. This plugin works only with File URI.
+
+Adding the plugin to your project
+
+ 1) To install the plugin, move the file camera.js to your project's www folder and include a reference to it in your html files.
+ 2) Put the Java files in your src/ folder.
+ 3) Change the default Camera Plugin into res/xml/plugins.xml file to <plugin name="Camera" value="<path to your ForegroundCameraLauncher.java>"/>.
+ 4) Put the strings.xml in your res/values folder.
+ 5) Put the foregroundcameraplugin.xml in your res/layout folder.
+ 6) In you AndroidManifest.xml, put this permissions:
+ <uses-feature android:name="android.hardware.camera" />
+ <uses-feature android:name="android.hardware.camera.autofocus" />
+ And declare the Camera Activity:
+ <activity
+ android:name=".CameraActivity"
+ android:label="ForegroundCameraPlugin"
+ android:screenOrientation="landscape" >
+ </activity>
+
+Using the plugin
+
+ See the index.xhtml.
View
9 Android/ForegroundCamera/Sample/ForegroundCameraPlugin/.classpath
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="src" path="gen"/>
+ <classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
+ <classpathentry kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
+ <classpathentry kind="lib" path="libs/cordova-2.1.0.jar"/>
+ <classpathentry kind="output" path="bin/classes"/>
+</classpath>
View
33 Android/ForegroundCamera/Sample/ForegroundCameraPlugin/.project
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>ForegroundCameraPlugin</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>com.android.ide.eclipse.adt.ApkBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>com.android.ide.eclipse.adt.AndroidNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
View
61 Android/ForegroundCamera/Sample/ForegroundCameraPlugin/AndroidManifest.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2012 Bruno Carreira - Lucas Farias - Rafael Luna - Vinícius Fonseca.
+
+ Licensed 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.foregroundcameraplugin"
+ android:versionCode="1"
+ android:versionName="1.1" >
+
+ <supports-screens
+ android:anyDensity="true"
+ android:largeScreens="true"
+ android:normalScreens="true"
+ android:resizeable="false"
+ android:smallScreens="true" />
+
+ <uses-permission android:name="android.permission.CAMERA" />
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+ <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+
+ <uses-feature android:name="android.hardware.camera" />
+ <uses-feature android:name="android.hardware.camera.autofocus" />
+
+ <uses-sdk
+ android:minSdkVersion="7"
+ android:targetSdkVersion="7" />
+
+ <application
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name" >
+ <activity
+ android:name=".App"
+ android:configChanges="orientation|keyboardHidden" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ <activity
+ android:name="org.apache.cordova.DroidGap"
+ android:configChanges="orientation|keyboardHidden"
+ android:label="@string/app_name" />
+ <activity
+ android:name=".CameraActivity"
+ android:label="ForegroundCameraPlugin"
+ android:screenOrientation="landscape" />
+ </application>
+
+</manifest>
View
202 Android/ForegroundCamera/Sample/ForegroundCameraPlugin/LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed 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.
View
9 Android/ForegroundCamera/Sample/ForegroundCameraPlugin/NOTICE
@@ -0,0 +1,9 @@
+Foreground Camera Plugin for Phonegap (Cordova)
+Copyright 2012 Bruno Carreira - Lucas Farias - Rafael Luna - Vin�cius Fonseca.
+
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org)
+
+- src/com/foregroundcameraplugin/ForegroundCameraLauncher.java was based on CameraLauncher.java, found in Phonegap (Apache Cordova) version 1.8.0.
+- assets/www/js/camera.js was based on cordova-1.8.0.js, found in Phonegap (Apache Cordova) version 1.8.0.
+- res/xml/plugins.xml was adapted from plugins.xml, found in Phonegap (Apache Cordova) version 1.8.0.
View
49 Android/ForegroundCamera/Sample/ForegroundCameraPlugin/README.txt
@@ -0,0 +1,49 @@
+ Copyright 2012 Bruno Carreira - Lucas Farias - Rafael Luna - Vin�cius Fonseca.
+
+ Licensed 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.
+
+Foreground Camera Plugin for Phonegap (Cordova).
+
+Originally by: - Bruno Carreira
+ - Lucas Farias
+ - Rafael Luna
+ - Vinicius Fonseca
+
+The default Phonegap (Cordova) Camera Plugin calls the native camera and this makes Android Garbage Collector to kill background applications. This plugin avoid your application to go background and be killed by Garbage Collector with other applications. We used the Phonegap source code and modified it to avoid this problem. This plugin works only with File URI.
+
+Adding the plugin to your project
+
+ 1) To install the plugin, move the file camera.js to your project's www folder and include a reference to it in your html files.
+ 2) Put the Java files in your src/ folder.
+ 3) Change the default Camera Plugin into res/xml/config.xml file to <plugin name="Camera" value="<path to your ForegroundCameraLauncher.java>"/>.
+ 4) Put the strings.xml in your res/values folder.
+ 5) Put the foregroundcameraplugin.xml in your res/layout folder.
+ 6) In you AndroidManifest.xml, put this permissions:
+
+ <uses-permission android:name="android.permission.CAMERA" />
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+ <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+
+ <uses-feature android:name="android.hardware.camera" />
+ <uses-feature android:name="android.hardware.camera.autofocus" />
+
+ And declare the Camera Activity:
+ <activity
+ android:name=".CameraActivity"
+ android:label="ForegroundCameraPlugin"
+ android:screenOrientation="landscape" >
+ </activity>
+
+Using the plugin
+
+ See the index.xhtml.
View
83 Android/ForegroundCamera/Sample/ForegroundCameraPlugin/assets/www/index.html
@@ -0,0 +1,83 @@
+<!--
+ Copyright 2012 Bruno Carreira - Lucas Farias - Rafael Luna - Vin�cius Fonseca.
+
+ Licensed 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.
+ -->
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Capture Photo</title>
+
+ <script src="js/cordova-2.1.0.js"></script>
+ <script type="text/javascript" src="js/camera.js"></script>
+ <script type="text/javascript" charset="utf-8">
+
+ var pictureSource; // picture source
+ var destinationType; // sets the format of returned value
+
+ // Wait for PhoneGap to connect with the device
+ //
+ document.addEventListener("deviceready",onDeviceReady,false);
+
+ // PhoneGap is ready to be used!
+ //
+ function onDeviceReady() {
+ pictureSource=navigator.camera.PictureSourceType;
+ destinationType=navigator.camera.DestinationType;
+ }
+
+ // Called when a photo is successfully retrieved
+ //
+ function onPhotoDataSuccess(imageData) {
+ // Uncomment to view the base64 encoded image data
+ console.log("---> Image: "+imageData);
+
+ // Get image handle
+ //
+ var smallImage = document.getElementById('smallImage');
+
+ // Unhide image elements
+ //
+ smallImage.style.display = 'block';
+
+ // Show the captured photo
+ // The inline CSS rules are used to resize the image
+ //
+ smallImage.src = imageData;
+ }
+
+ // Called if something bad happens.
+ //
+ function onFail(message) {
+ alert('Failed because: ' + message);
+ }
+
+ // A button will call this function
+ //
+ function capturePhoto() {
+ // Take picture using device camera and retrieve image as base64-encoded string
+ navigator.camera.getPicture(onPhotoDataSuccess, onFail,
+ {
+ quality: 70,
+ targetWidth: 800,
+ targetHeight: 600
+ });
+ }
+
+ </script>
+ </head>
+ <body>
+ <button onclick="capturePhoto();">Capture Photo</button> <br>
+ <img style="display:none;width:160px;height:160px;" id="smallImage" src="" />
+ </body>
+</html>
View
91 Android/ForegroundCamera/Sample/ForegroundCameraPlugin/assets/www/js/camera.js
@@ -0,0 +1,91 @@
+/**
+ Copyright 2012 Bruno Carreira - Lucas Farias - Rafael Luna - Vin�cius Fonseca.
+
+ Licensed 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.
+*/
+
+/**
+ * This class provides access to the device camera.
+ *
+ * @constructor
+ */
+var Camera = function() {
+ this.successCallback = null;
+ this.errorCallback = null;
+ this.options = null;
+};
+
+/**
+ * Gets a picture from source defined by "options.sourceType", and returns the
+ * image as defined by the "options.destinationType" option.
+
+ * The defaults are sourceType=CAMERA and destinationType=DATA_URL.
+ *
+ * @param {Function} successCallback
+ * @param {Function} errorCallback
+ * @param {Object} options
+ */
+Camera.prototype.getPicture = function(successCallback, errorCallback,
+ options) {
+
+ // successCallback required
+ if (typeof successCallback !== "function") {
+ console.log("Camera Error: successCallback is not a function");
+ return;
+ }
+
+ // errorCallback optional
+ if (errorCallback && (typeof errorCallback !== "function")) {
+ console.log("Camera Error: errorCallback is not a function");
+ return;
+ }
+
+ if (options === null || typeof options === "undefined") {
+ options = {};
+ }
+ if (options.quality === null || typeof options.quality === "undefined") {
+ options.quality = 80;
+ }
+ if (options.maxResolution === null
+ || typeof options.maxResolution === "undefined") {
+ options.maxResolution = 0;
+ }
+
+ if (options.targetWidth === null
+ || typeof options.targetWidth === "undefined") {
+ options.targetWidth = -1;
+ } else if (typeof options.targetWidth === "string") {
+ var width = new Number(options.targetWidth);
+ if (isNaN(width) === false) {
+ options.targetWidth = width.valueOf();
+ }
+ }
+ if (options.targetHeight === null
+ || typeof options.targetHeight === "undefined") {
+ options.targetHeight = -1;
+ } else if (typeof options.targetHeight === "string") {
+ var height = new Number(options.targetHeight);
+ if (isNaN(height) === false) {
+ options.targetHeight = height.valueOf();
+ }
+ }
+
+ cordova.exec(successCallback, errorCallback, "Camera", "takePicture",
+ [ options ]);
+};
+
+cordova.addConstructor(function() {
+ if (typeof navigator.camera === "undefined") {
+ navigator.camera = new Camera();
+ }
+});
View
5,814 Android/ForegroundCamera/Sample/ForegroundCameraPlugin/assets/www/js/cordova-2.1.0.js
5,814 additions, 0 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
View
BIN Android/ForegroundCamera/Sample/ForegroundCameraPlugin/libs/cordova-2.1.0.jar
Binary file not shown.
View
11 Android/ForegroundCamera/Sample/ForegroundCameraPlugin/project.properties
@@ -0,0 +1,11 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system use,
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+
+# Project target.
+target=android-7
View
BIN Android/ForegroundCamera/Sample/ForegroundCameraPlugin/res/drawable-hdpi/ic_launcher.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN Android/ForegroundCamera/Sample/ForegroundCameraPlugin/res/drawable-ldpi/ic_launcher.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN Android/ForegroundCamera/Sample/ForegroundCameraPlugin/res/drawable-mdpi/ic_launcher.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
48 Android/ForegroundCamera/Sample/ForegroundCameraPlugin/res/layout/foregroundcameraplugin.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2012 Bruno Carreira - Lucas Farias - Rafael Luna - Vinícius Fonseca.
+
+ Licensed 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.
+ -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:baselineAligned="true"
+ android:orientation="horizontal" >
+
+ <FrameLayout
+ android:id="@+id/camera_preview"
+ android:layout_width="0dp"
+ android:layout_height="fill_parent"
+ android:layout_weight="0.85" />
+
+ <LinearLayout
+ android:id="@+id/linearLayout1"
+ android:layout_width="wrap_content"
+ android:layout_height="fill_parent"
+ android:orientation="vertical" >
+
+ <Button
+ android:id="@+id/button_capture"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/lblCapturar" />
+
+ <Button
+ android:id="@+id/button_cancel"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/lblCancelar" />
+ </LinearLayout>
+
+</LinearLayout>
View
22 Android/ForegroundCamera/Sample/ForegroundCameraPlugin/res/values/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2012 Bruno Carreira - Lucas Farias - Rafael Luna - Vinícius Fonseca.
+
+ Licensed 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.
+ -->
+<resources>
+ <string name="hello">Hello Foreground Camera Plugin!</string>
+ <string name="app_name">Foreground Camera Plugin</string>
+ <string name="lblCapturar">Capture</string>
+ <string name="lblCancelar">Cancel</string>
+</resources>
View
58 Android/ForegroundCamera/Sample/ForegroundCameraPlugin/res/xml/config.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<cordova>
+ <!--
+ access elements control the Android whitelist.
+ Domains are assumed blocked unless set otherwise
+ -->
+
+ <access origin="http://127.0.0.1*"/> <!-- allow local pages -->
+
+ <!-- <access origin="https://example.com" /> allow any secure requests to example.com -->
+ <!-- <access origin="https://example.com" subdomains="true" /> such as above, but including subdomains, such as www -->
+ <!-- <access origin=".*"/> Allow all domains, suggested development use only -->
+
+ <log level="DEBUG"/>
+ <preference name="useBrowserHistory" value="false" />
+<plugins>
+ <plugin name="App" value="org.apache.cordova.App"/>
+ <plugin name="Geolocation" value="org.apache.cordova.GeoBroker"/>
+ <plugin name="Device" value="org.apache.cordova.Device"/>
+ <plugin name="Accelerometer" value="org.apache.cordova.AccelListener"/>
+ <plugin name="Compass" value="org.apache.cordova.CompassListener"/>
+ <plugin name="Media" value="org.apache.cordova.AudioHandler"/>
+ <!-- <plugin name="Camera" value="org.apache.cordova.CameraLauncher"/> -->
+ <plugin name="Contacts" value="org.apache.cordova.ContactManager"/>
+ <plugin name="File" value="org.apache.cordova.FileUtils"/>
+ <plugin name="NetworkStatus" value="org.apache.cordova.NetworkManager"/>
+ <plugin name="Notification" value="org.apache.cordova.Notification"/>
+ <plugin name="Storage" value="org.apache.cordova.Storage"/>
+ <plugin name="Temperature" value="org.apache.cordova.TempListener"/>
+ <plugin name="FileTransfer" value="org.apache.cordova.FileTransfer"/>
+ <plugin name="Capture" value="org.apache.cordova.Capture"/>
+ <plugin name="Battery" value="org.apache.cordova.BatteryListener"/>
+ <plugin name="SplashScreen" value="org.apache.cordova.SplashScreen"/>
+
+ <!-- Plugin to camera -->
+ <plugin name="Camera" value="com.foregroundcameraplugin.ForegroundCameraLauncher"/>
+
+</plugins>
+</cordova>
+
View
33 ...id/ForegroundCamera/Sample/ForegroundCameraPlugin/src/com/foregroundcameraplugin/App.java
@@ -0,0 +1,33 @@
+/*
+ Copyright 2012 Bruno Carreira - Lucas Farias - Rafael Luna - Vinícius Fonseca.
+
+ Licensed 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 com.foregroundcameraplugin;
+
+import org.apache.cordova.DroidGap;
+import android.os.Bundle;
+
+/**
+ * App class.
+ * Opens index.html file to test the camera. *
+ */
+public class App extends DroidGap {
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ super.loadUrl("file:///android_asset/www/index.html");
+ }
+}
View
136 ...ndCamera/Sample/ForegroundCameraPlugin/src/com/foregroundcameraplugin/CameraActivity.java
@@ -0,0 +1,136 @@
+/*
+ Copyright 2012 Bruno Carreira - Lucas Farias - Rafael Luna - Vinícius Fonseca.
+
+ Licensed 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 com.foregroundcameraplugin;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import android.app.Activity;
+import android.hardware.Camera;
+import android.hardware.Camera.AutoFocusCallback;
+import android.hardware.Camera.PictureCallback;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.MediaStore;
+import android.util.Log;
+import android.view.View;
+import android.widget.Button;
+import android.widget.FrameLayout;
+
+/**
+ * Camera Activity Class. Configures Android camera to take picture and show it.
+ */
+public class CameraActivity extends Activity {
+
+ private static final String TAG = "CameraActivity";
+
+ private Camera mCamera;
+ private ForegroundCameraPreview mPreview;
+ private boolean pressed = false;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.foregroundcameraplugin);
+
+ // Create an instance of Camera
+ mCamera = getCameraInstance();
+
+ // Create a Preview and set it as the content of activity.
+ mPreview = new ForegroundCameraPreview(this, mCamera);
+ FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
+ preview.addView(mPreview);
+
+ // Add a listener to the Capture button
+ Button captureButton = (Button) findViewById(R.id.button_capture);
+ captureButton.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+
+ if (pressed)
+ return;
+
+ // Set pressed = true to prevent freezing.
+ // Issue 1 at
+ // http://code.google.com/p/foreground-camera-plugin/issues/detail?id=1
+ pressed = true;
+
+ // get an image from the camera
+ mCamera.autoFocus(new AutoFocusCallback() {
+
+ public void onAutoFocus(boolean success, Camera camera) {
+ mCamera.takePicture(null, null, mPicture);
+ }
+ });
+ }
+ });
+
+ Button cancelButton = (Button) findViewById(R.id.button_cancel);
+ cancelButton.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ pressed = false;
+ setResult(RESULT_CANCELED);
+ finish();
+ }
+ });
+ }
+
+ @Override
+ protected void onPause() {
+ if (mCamera != null) {
+ mCamera.release(); // release the camera for other applications
+ mCamera = null;
+ }
+ super.onPause();
+ }
+
+ /** A safe way to get an instance of the Camera object. */
+ public static Camera getCameraInstance() {
+ Camera c = null;
+ try {
+ c = Camera.open(); // attempt to get a Camera instance
+ } catch (Exception e) {
+ // Camera is not available (in use or does not exist)
+ }
+ return c; // returns null if camera is unavailable
+ }
+
+ private PictureCallback mPicture = new PictureCallback() {
+
+ public void onPictureTaken(byte[] data, Camera camera) {
+
+ Uri fileUri = (Uri) getIntent().getExtras().get(
+ MediaStore.EXTRA_OUTPUT);
+
+ File pictureFile = new File(fileUri.getPath());
+
+ try {
+ FileOutputStream fos = new FileOutputStream(pictureFile);
+ fos.write(data);
+ fos.close();
+ } catch (FileNotFoundException e) {
+ Log.d(TAG, "File not found: " + e.getMessage());
+ } catch (IOException e) {
+ Log.d(TAG, "Error accessing file: " + e.getMessage());
+ }
+ setResult(RESULT_OK);
+ pressed = false;
+ finish();
+ }
+ };
+}
View
380 ...ample/ForegroundCameraPlugin/src/com/foregroundcameraplugin/ForegroundCameraLauncher.java
@@ -0,0 +1,380 @@
+/*
+ Copyright 2012 Bruno Carreira - Lucas Farias - Rafael Luna - Vin�cius Fonseca.
+
+ Licensed 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 com.foregroundcameraplugin;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.apache.cordova.CameraLauncher;
+import org.apache.cordova.ExifHelper;
+import org.apache.cordova.api.CordovaInterface;
+import org.apache.cordova.api.LOG;
+import org.apache.cordova.api.Plugin;
+import org.apache.cordova.api.PluginResult;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import android.app.Activity;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.Intent;
+import android.database.Cursor;
+import android.graphics.Bitmap;
+import android.net.Uri;
+import android.os.Environment;
+import android.provider.MediaStore;
+
+/**
+ * This class launches the camera view, allows the user to take a picture,
+ * closes the camera view, and returns the captured image. When the camera view
+ * is closed, the screen displayed before the camera view was shown is
+ * redisplayed.
+ */
+public class ForegroundCameraLauncher extends CameraLauncher {
+
+ private static final String LOG_TAG = "ForegroundCameraLauncher";
+
+ private int mQuality;
+ private int targetWidth;
+ private int targetHeight;
+
+ private Uri imageUri;
+ private File photo;
+
+ public String callbackId;
+ private int numPics;
+
+ private static final String _DATA = "_data";
+
+ /**
+ * Constructor.
+ */
+ public ForegroundCameraLauncher() {
+ }
+
+ /**
+ * Executes the request and returns PluginResult.
+ *
+ * @param action
+ * The action to execute.
+ * @param args
+ * JSONArry of arguments for the plugin.
+ * @param callbackId
+ * The callback id used when calling back into JavaScript.
+ * @return A PluginResult object with a status and message.
+ */
+ public PluginResult execute(String action, JSONArray args, String callbackId) {
+ PluginResult.Status status = PluginResult.Status.OK;
+ String result = "";
+ this.callbackId = callbackId;
+
+ try {
+ if (action.equals("takePicture")) {
+ this.targetHeight = 0;
+ this.targetWidth = 0;
+ this.mQuality = 80;
+
+ JSONObject options = args.optJSONObject(0);
+ if (options != null) {
+ this.targetHeight = options.getInt("targetHeight");
+ this.targetWidth = options.getInt("targetWidth");
+ this.mQuality = options.getInt("quality");
+ }
+
+ this.takePicture();
+
+ PluginResult r = new PluginResult(PluginResult.Status.NO_RESULT);
+ r.setKeepCallback(true);
+ return r;
+ }
+ return new PluginResult(status, result);
+ } catch (JSONException e) {
+ e.printStackTrace();
+ return new PluginResult(PluginResult.Status.JSON_EXCEPTION);
+ }
+ }
+
+ // --------------------------------------------------------------------------
+ // LOCAL METHODS
+ // --------------------------------------------------------------------------
+
+ /**
+ * Take a picture with the camera. When an image is captured or the camera
+ * view is cancelled, the result is returned in
+ * CordovaActivity.onActivityResult, which forwards the result to
+ * this.onActivityResult.
+ *
+ * The image can either be returned as a base64 string or a URI that points
+ * to the file. To display base64 string in an img tag, set the source to:
+ * img.src="data:image/jpeg;base64,"+result; or to display URI in an img tag
+ * img.src=result;
+ *
+ */
+ public void takePicture() {
+ // Save the number of images currently on disk for later
+ this.numPics = queryImgDB().getCount();
+
+ Intent intent = new Intent(this.cordova.getActivity().getApplicationContext(), CameraActivity.class);
+ this.photo = createCaptureFile();
+ this.imageUri = Uri.fromFile(photo);
+ intent.putExtra(MediaStore.EXTRA_OUTPUT, this.imageUri);
+
+ this.cordova.startActivityForResult((Plugin) this, intent, 1);
+ }
+
+ /**
+ * Create a file in the applications temporary directory based upon the
+ * supplied encoding.
+ *
+ * @return a File object pointing to the temporary picture
+ */
+ private File createCaptureFile() {
+ File photo = new File(getTempDirectoryPath(this.cordova.getActivity().getApplicationContext()), "Pic.jpg");
+ return photo;
+ }
+
+ /**
+ * Called when the camera view exits.
+ *
+ * @param requestCode
+ * The request code originally supplied to
+ * startActivityForResult(), allowing you to identify who this
+ * result came from.
+ * @param resultCode
+ * The integer result code returned by the child activity through
+ * its setResult().
+ * @param intent
+ * An Intent, which can return result data to the caller (various
+ * data can be attached to Intent "extras").
+ */
+ public void onActivityResult(int requestCode, int resultCode, Intent intent) {
+
+ // If image available
+ if (resultCode == Activity.RESULT_OK) {
+ try {
+ // Create an ExifHelper to save the exif data that is lost
+ // during compression
+ ExifHelper exif = new ExifHelper();
+ exif.createInFile(getTempDirectoryPath(this.cordova.getActivity().getApplicationContext())
+ + "/Pic.jpg");
+ exif.readExifData();
+
+ // Read in bitmap of captured image
+ Bitmap bitmap;
+ try {
+ bitmap = android.provider.MediaStore.Images.Media
+ .getBitmap(this.cordova.getActivity().getContentResolver(), imageUri);
+ } catch (FileNotFoundException e) {
+ Uri uri = intent.getData();
+ android.content.ContentResolver resolver = this.cordova.getActivity().getContentResolver();
+ bitmap = android.graphics.BitmapFactory
+ .decodeStream(resolver.openInputStream(uri));
+ }
+
+ bitmap = scaleBitmap(bitmap);
+
+ // 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.");
+ 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;
+ }
+ }
+
+ // 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
+ exif.createOutFile(getRealPathFromURI(uri, this.ctx));
+ exif.writeExifData();
+
+ // Send Uri back to JavaScript for viewing image
+ this.success(new PluginResult(PluginResult.Status.OK,
+ getRealPathFromURI(uri, this.ctx)), this.callbackId);
+
+ bitmap.recycle();
+ bitmap = null;
+ System.gc();
+
+ checkForDuplicateImage();
+ } catch (IOException e) {
+ e.printStackTrace();
+ this.failPicture("Error capturing image.");
+ }
+ }
+
+ // If cancelled
+ else if (resultCode == Activity.RESULT_CANCELED) {
+ this.failPicture("Camera cancelled.");
+ }
+
+ // If something else
+ else {
+ this.failPicture("Did not complete!");
+ }
+ }
+
+ /**
+ * 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;
+ }
+ }
+
+ return Bitmap.createScaledBitmap(bitmap, newWidth, newHeight, true);
+ }
+
+ /**
+ * Creates a cursor that can be used to determine how many images we have.
+ *
+ * @return a cursor
+ */
+ private Cursor queryImgDB() {
+ return this.cordova.getActivity().getContentResolver().query(
+ android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
+ new String[] { MediaStore.Images.Media._ID }, null, null, null);
+ }
+
+ /**
+ * Used to find out if we are in a situation where the Camera Intent adds to
+ * images to the content store. If we are using a FILE_URI and the number of
+ * images in the DB increases by 2 we have a duplicate, when using a
+ * DATA_URL the number is 1.
+ */
+ private void checkForDuplicateImage() {
+ int diff = 2;
+ Cursor cursor = queryImgDB();
+ int currentNumOfImages = cursor.getCount();
+
+ // delete the duplicate file if the difference is 2 for file URI or 1
+ // for Data URL
+ if ((currentNumOfImages - numPics) == diff) {
+ cursor.moveToLast();
+ int id = Integer.valueOf(cursor.getString(cursor
+ .getColumnIndex(MediaStore.Images.Media._ID))) - 1;
+ Uri uri = Uri.parse(MediaStore.Images.Media.EXTERNAL_CONTENT_URI
+ + "/" + id);
+ this.cordova.getActivity().getContentResolver().delete(uri, null, null);
+ }
+ }
+
+ /**
+ * Determine if we can use the SD Card to store the temporary file. If not
+ * then use the internal cache directory.
+ *
+ * @return the absolute path of where to store the file
+ */
+ private String getTempDirectoryPath(Context ctx) {
+ File cache = null;
+
+ // SD Card Mounted
+ if (Environment.getExternalStorageState().equals(
+ Environment.MEDIA_MOUNTED)) {
+ cache = new File(Environment.getExternalStorageDirectory()
+ .getAbsolutePath()
+ + "/Android/data/"
+ + ctx.getPackageName() + "/cache/");
+ }
+ // Use internal storage
+ else {
+ cache = ctx.getCacheDir();
+ }
+
+ // Create the cache directory if it doesn't exist
+ if (!cache.exists()) {
+ cache.mkdirs();
+ }
+
+ return cache.getAbsolutePath();
+ }
+
+ /**
+ * 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 ctx
+ * the current applicaiton context
+ * @return the full path to the file
+ */
+ private String getRealPathFromURI(Uri contentUri, CordovaInterface ctx) {
+ 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);
+ }
+}
View
73 ...Sample/ForegroundCameraPlugin/src/com/foregroundcameraplugin/ForegroundCameraPreview.java
@@ -0,0 +1,73 @@
+/*
+ Copyright 2012 Bruno Carreira - Lucas Farias - Rafael Luna - Vinícius Fonseca.
+
+ Licensed 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 com.foregroundcameraplugin;
+
+import java.io.IOException;
+
+import android.content.Context;
+import android.hardware.Camera;
+import android.util.Log;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+
+public class ForegroundCameraPreview extends SurfaceView implements SurfaceHolder.Callback {
+ private SurfaceHolder mHolder;
+ private Camera mCamera;
+ private static final String TAG = "CameraPreview";
+
+ public ForegroundCameraPreview(Context context, Camera camera) {
+ super(context);
+ mCamera = camera;
+
+ mHolder = getHolder();
+ mHolder.addCallback(this);
+ mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
+ }
+
+ public void surfaceCreated(SurfaceHolder holder) {
+ try {
+ mCamera.setPreviewDisplay(holder);
+ mCamera.startPreview();
+ } catch (IOException e) {
+ Log.d(TAG, "Error setting camera preview: " + e.getMessage());
+ }
+ }
+
+ public void surfaceDestroyed(SurfaceHolder holder) {
+ }
+
+
+ public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
+
+ if (mHolder.getSurface() == null){
+ return;
+ }
+
+ try {
+ mCamera.stopPreview();
+ } catch (Exception e){
+ }
+
+ try {
+ mCamera.setPreviewDisplay(mHolder);
+ mCamera.startPreview();
+
+ } catch (Exception e){
+ Log.d(TAG, "Error starting camera preview: " + e.getMessage());
+ }
+ }
+}
View
91 Android/ForegroundCamera/camera.js
@@ -0,0 +1,91 @@
+/**
+ Copyright 2012 Bruno Carreira - Lucas Farias - Rafael Luna - Vin�cius Fonseca.
+
+ Licensed 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.
+*/
+
+/**
+ * This class provides access to the device camera.
+ *
+ * @constructor
+ */
+var Camera = function() {
+ this.successCallback = null;
+ this.errorCallback = null;
+ this.options = null;
+};
+
+/**
+ * Gets a picture from source defined by "options.sourceType", and returns the
+ * image as defined by the "options.destinationType" option.
+
+ * The defaults are sourceType=CAMERA and destinationType=DATA_URL.
+ *
+ * @param {Function} successCallback
+ * @param {Function} errorCallback
+ * @param {Object} options
+ */
+Camera.prototype.getPicture = function(successCallback, errorCallback,
+ options) {
+
+ // successCallback required
+ if (typeof successCallback !== "function") {
+ console.log("Camera Error: successCallback is not a function");
+ return;
+ }
+
+ // errorCallback optional
+ if (errorCallback && (typeof errorCallback !== "function")) {
+ console.log("Camera Error: errorCallback is not a function");
+ return;
+ }
+
+ if (options === null