package org.cloudsky.cordovaPlugins; import java.io.IOException; import java.lang.RuntimeException; import org.json.JSONException; import org.json.JSONObject; import android.app.Activity; import android.content.Intent; import android.content.res.Resources; import android.hardware.Camera; import android.hardware.Camera.CameraInfo; import android.hardware.Camera.PreviewCallback; import android.hardware.Camera.AutoFocusCallback; import android.os.Bundle; import android.os.Handler; import android.util.Log; import android.view.Gravity; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; import android.widget.TextView; import net.sourceforge.zbar.ImageScanner; import net.sourceforge.zbar.Image; import net.sourceforge.zbar.Symbol; import net.sourceforge.zbar.SymbolSet; import net.sourceforge.zbar.Config; public class ZBarScannerActivity extends Activity implements SurfaceHolder.Callback { // Config ---------------------------------------------------------- private static int autoFocusInterval = 500; // Interval between AFcallback and next AF attempt. // Public Constants ------------------------------------------------ public static final String EXTRA_QRVALUE = "qrValue"; public static final String EXTRA_PARAMS = "params"; public static final int RESULT_ERROR = RESULT_FIRST_USER + 1; // State ----------------------------------------------------------- private Camera camera; private Handler autoFocusHandler; private SurfaceView scannerSurface; private SurfaceHolder holder; private ImageScanner scanner; private int surfW, surfH; // Customisable stuff String whichCamera; String flashMode; // For retrieving R.* resources, from the actual app package // (we can't use actual.application.package.R.* in our code as we // don't know the applciation package name when writing this plugin). private String package_name; private Resources resources; // Static initialisers (class) ------------------------------------- static { // Needed by ZBar?? System.loadLibrary("iconv"); } // Activity Lifecycle ---------------------------------------------- @Override public void onCreate (Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Get parameters from JS Intent startIntent = getIntent(); String paramStr = startIntent.getStringExtra(EXTRA_PARAMS); JSONObject params; try { params = new JSONObject(paramStr); } catch (JSONException e) { params = new JSONObject(); } String textTitle = params.optString("text_title"); String textInstructions = params.optString("text_instructions"); Boolean drawSight = params.optBoolean("drawSight", true); whichCamera = params.optString("camera"); flashMode = params.optString("flash"); // Initiate instance variables autoFocusHandler = new Handler(); scanner = new ImageScanner(); scanner.setConfig(0, Config.X_DENSITY, 3); scanner.setConfig(0, Config.Y_DENSITY, 3); // Set content view setContentView(getResourceId("layout/cszbarscanner")); // Update view with customisable strings TextView view_textTitle = (TextView) findViewById(getResourceId("id/csZbarScannerTitle")); TextView view_textInstructions = (TextView) findViewById(getResourceId("id/csZbarScannerInstructions")); view_textTitle.setText(textTitle); view_textInstructions.setText(textInstructions); // Draw/hide the sight if(!drawSight) { findViewById(getResourceId("id/csZbarScannerSight")).setVisibility(View.INVISIBLE); } // Create preview SurfaceView scannerSurface = new SurfaceView (this) { @Override public void onSizeChanged (int w, int h, int oldW, int oldH) { surfW = w; surfH = h; matchSurfaceToPreviewRatio(); } }; scannerSurface.setLayoutParams(new FrameLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, Gravity.CENTER )); scannerSurface.getHolder().addCallback(this); // Add preview SurfaceView to the screen FrameLayout scannerView = (FrameLayout) findViewById(getResourceId("id/csZbarScannerView")); scannerView.addView(scannerSurface); findViewById(getResourceId("id/csZbarScannerTitle")).bringToFront(); findViewById(getResourceId("id/csZbarScannerInstructions")).bringToFront(); findViewById(getResourceId("id/csZbarScannerSightContainer")).bringToFront(); findViewById(getResourceId("id/csZbarScannerSight")).bringToFront(); scannerView.requestLayout(); scannerView.invalidate(); } @Override public void onResume () { super.onResume(); try { if(whichCamera.equals("front")) { int numCams = Camera.getNumberOfCameras(); CameraInfo cameraInfo = new CameraInfo(); for(int i=0; i surfaceRatio) { scannerSurface.setLayoutParams(new FrameLayout.LayoutParams( surfW, Math.round((float) surfW / previewRatio), Gravity.CENTER )); } else if(previewRatio < surfaceRatio) { scannerSurface.setLayoutParams(new FrameLayout.LayoutParams( Math.round((float) surfH * previewRatio), surfH, Gravity.CENTER )); } } // Stop the camera preview safely. private void tryStopPreview () { // Stop camera preview before making changes. try { camera.stopPreview(); } catch (Exception e){ // Preview was not running. Ignore the error. } } // Start the camera preview if possible. // If start is attempted but fails, exit with error message. private void tryStartPreview () { if(holder != null) { try { // 90 degrees rotation for Portrait orientation Activity. camera.setDisplayOrientation(90); camera.setPreviewDisplay(holder); camera.setPreviewCallback(previewCb); camera.startPreview(); camera.autoFocus(autoFocusCb); // We are not using any of the // continuous autofocus modes as that does not seem to work // well with flash setting of "on"... At least with this // simple and stupid focus method, we get to turn the flash // on during autofocus. } catch (IOException e) { die("Could not start camera preview: " + e.getMessage()); } } } }