package com.prey.barcodereader; import android.Manifest; import android.annotation.SuppressLint; import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; import android.hardware.Camera; import android.os.Build; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.design.widget.Snackbar; import android.support.v4.app.ActivityCompat; import android.support.v7.app.AppCompatActivity; import android.view.GestureDetector; import android.view.MotionEvent; import android.view.ScaleGestureDetector; import android.view.View; import android.widget.Toast; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.GoogleApiAvailability; import com.google.android.gms.common.api.CommonStatusCodes; import com.prey.PreyLogger; import com.prey.barcodereader.ui.camera.CameraSource; import com.prey.barcodereader.ui.camera.CameraSourcePreview; import com.prey.barcodereader.ui.camera.GraphicOverlay; import com.google.android.gms.vision.MultiProcessor; import com.google.android.gms.vision.barcode.Barcode; import com.google.android.gms.vision.barcode.BarcodeDetector; import com.prey.R; import java.io.IOException; public final class BarcodeCaptureActivity extends AppCompatActivity { private static final int RC_HANDLE_GMS = 9001; private static final int RC_HANDLE_CAMERA_PERM = 2; public static final String AutoFocus = "AutoFocus"; public static final String UseFlash = "UseFlash"; public static final String BarcodeObject = "Barcode"; private CameraSource mCameraSource; private CameraSourcePreview mPreview; private GraphicOverlay<BarcodeGraphic> mGraphicOverlay; private ScaleGestureDetector scaleGestureDetector; private GestureDetector gestureDetector; @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); getSupportActionBar().hide(); setContentView(R.layout.barcode_capture); mPreview = (CameraSourcePreview) findViewById(R.id.preview); mGraphicOverlay = (GraphicOverlay<BarcodeGraphic>) findViewById(R.id.graphicOverlay); boolean autoFocus = getIntent().getBooleanExtra(AutoFocus, false); boolean useFlash = getIntent().getBooleanExtra(UseFlash, false); int rc = ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA); if (rc == PackageManager.PERMISSION_GRANTED) { createCameraSource(autoFocus, useFlash); } else { requestCameraPermission(); } gestureDetector = new GestureDetector(this, new CaptureGestureListener()); scaleGestureDetector = new ScaleGestureDetector(this, new ScaleListener()); } private void requestCameraPermission() { PreyLogger.d("Camera permission is not granted. Requesting permission"); final String[] permissions = new String[]{Manifest.permission.CAMERA}; if (!ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) { ActivityCompat.requestPermissions(this, permissions, RC_HANDLE_CAMERA_PERM); return; } final Activity thisActivity = this; View.OnClickListener listener = new View.OnClickListener() { @Override public void onClick(View view) { ActivityCompat.requestPermissions(thisActivity, permissions, RC_HANDLE_CAMERA_PERM); } }; Snackbar.make(mGraphicOverlay, R.string.permission_camera_rationale, Snackbar.LENGTH_INDEFINITE) .setAction(R.string.ok, listener) .show(); } @Override public boolean onTouchEvent(MotionEvent e) { boolean b = scaleGestureDetector.onTouchEvent(e); boolean c = gestureDetector.onTouchEvent(e); return b || c || super.onTouchEvent(e); } @SuppressLint("InlinedApi") private void createCameraSource(boolean autoFocus, boolean useFlash) { Context context = getApplicationContext(); BarcodeDetector barcodeDetector = new BarcodeDetector.Builder(context).build(); BarcodeTrackerFactory barcodeFactory = new BarcodeTrackerFactory(mGraphicOverlay,this); barcodeDetector.setProcessor( new MultiProcessor.Builder<>(barcodeFactory).build()); if (!barcodeDetector.isOperational()) { PreyLogger.d("Detector dependencies are not yet available."); IntentFilter lowstorageFilter = new IntentFilter(Intent.ACTION_DEVICE_STORAGE_LOW); boolean hasLowStorage = registerReceiver(null, lowstorageFilter) != null; if (hasLowStorage) { Toast.makeText(this, R.string.low_storage_error, Toast.LENGTH_LONG).show(); PreyLogger.d(getString(R.string.low_storage_error)); } } CameraSource.Builder builder = new CameraSource.Builder(getApplicationContext(), barcodeDetector) .setFacing(CameraSource.CAMERA_FACING_BACK) .setRequestedPreviewSize(1600, 1024) .setRequestedFps(15.0f); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { builder = builder.setFocusMode( autoFocus ? Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE : null); } mCameraSource = builder .setFlashMode(useFlash ? Camera.Parameters.FLASH_MODE_TORCH : null) .build(); } @Override protected void onResume() { super.onResume(); startCameraSource(); } @Override protected void onPause() { super.onPause(); if (mPreview != null) { mPreview.stop(); } } @Override protected void onDestroy() { super.onDestroy(); if (mPreview != null) { mPreview.release(); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { if (requestCode != RC_HANDLE_CAMERA_PERM) { PreyLogger.d("Got unexpected permission result: " + requestCode); super.onRequestPermissionsResult(requestCode, permissions, grantResults); return; } if (grantResults.length != 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { PreyLogger.d("Camera permission granted - initialize the camera source"); boolean autoFocus = getIntent().getBooleanExtra(AutoFocus,false); boolean useFlash = getIntent().getBooleanExtra(UseFlash, false); createCameraSource(autoFocus, useFlash); return; } PreyLogger.d("Permission not granted: results len = " + grantResults.length + " Result code = " + (grantResults.length > 0 ? grantResults[0] : "(empty)")); DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { finish(); } }; AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle("Multitracker sample") .setMessage(R.string.no_camera_permission) .setPositiveButton(R.string.ok, listener) .show(); } private void startCameraSource() throws SecurityException { int code = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable( getApplicationContext()); if (code != ConnectionResult.SUCCESS) { Dialog dlg = GoogleApiAvailability.getInstance().getErrorDialog(this, code, RC_HANDLE_GMS); dlg.show(); } if (mCameraSource != null) { try { mPreview.start(mCameraSource, mGraphicOverlay); } catch (IOException e) { PreyLogger.e("Unable to start camera source.", e); mCameraSource.release(); mCameraSource = null; } } } private boolean onTap(float rawX, float rawY) { BarcodeGraphic graphic = mGraphicOverlay.getFirstGraphic(); Barcode barcode = null; if (graphic != null) { barcode = graphic.getBarcode(); if (barcode != null) { PreyLogger.d("displayValue:"+barcode.displayValue); Intent data = new Intent(); data.putExtra(BarcodeObject, barcode); setResult(CommonStatusCodes.SUCCESS, data); finish(); } else { PreyLogger.d("barcode data is null"); } } else { PreyLogger.d("no barcode detected"); } return barcode != null; } public void updateBarcode(Barcode barcode) { if (barcode != null) { PreyLogger.d("displayValue:"+barcode.displayValue); Intent data = new Intent(); data.putExtra(BarcodeObject, barcode); setResult(CommonStatusCodes.SUCCESS, data); finish(); } } private class CaptureGestureListener extends GestureDetector.SimpleOnGestureListener { @Override public boolean onSingleTapConfirmed(MotionEvent e) { return onTap(e.getRawX(), e.getRawY()) || super.onSingleTapConfirmed(e); } } private class ScaleListener implements ScaleGestureDetector.OnScaleGestureListener { @Override public boolean onScale(ScaleGestureDetector detector) { return false; } @Override public boolean onScaleBegin(ScaleGestureDetector detector) { return true; } @Override public void onScaleEnd(ScaleGestureDetector detector) { mCameraSource.doZoom(detector.getScaleFactor()); } } }