public class BarcodeCaptureFragment extends BaseStackFragment implements BarcodeGraphicTracker.BarcodeUpdateListener, View.OnClickListener, CustomDialogFragment.IDialogEventListener {
public static final String TAG = BarcodeCaptureFragment.class.getName();
// intent request code to handle updating play services if needed. private static final int RC_HANDLE_GMS = 9001;
// permission request codes need to be < 256 private static final int RC_HANDLE_CAMERA_PERM = 2;
// constants used to pass extra data in the intent 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 RelativeLayout rlGiveYourBarCodeNumber;
private CameraSourcePreview preview;
private EditText tvManualEntry;
private RelativeLayout rlManualEntryBar;
private TextView tvBarCodeScanner;
private CustomDialogFragment customDialogFragment;
@Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.com_philips_lumea_barcode_capture, null);
}
@Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mPreview = (CameraSourcePreview) getView().findViewById(R.id.preview);
ImageView ivBarCodeBackButton = (ImageView) getView().findViewById(R.id.ivBarCodeBackButton);
ivBarCodeBackButton.setOnClickListener(this);
rlManualEntryBar = (RelativeLayout) getView().findViewById(R.id.rlManualEntryBar);
rlManualEntryBar.setOnClickListener(this);
rlGiveYourBarCodeNumber = (RelativeLayout) getView().findViewById(R.id.rlGiveYourBarCodeNumber);
rlGiveYourBarCodeNumber.setVisibility(View.GONE);
preview = (CameraSourcePreview) getView().findViewById(R.id.preview);
preview.setVisibility(View.VISIBLE);
tvManualEntry = (EditText) getView().findViewById(R.id.tvManualEntry);
tvBarCodeScanner = (TextView) getView().findViewById(R.id.tvBarCodeScanner);
}
private void checkCameraPermission() {
PermissionUtil.checkPermission(getActivity(), Manifest.permission.CAMERA, new PermissionUtil.PermissionAskListener() {
@Override public void onNeedPermission() {
requestCameraPermission();
}
@Override public void onPermissionPreviouslyDenied() {
requestCameraPermission();
}
@Override public void onPermissionDisabled() {
String dialogTitle = getResources().getString(R.string.com_philips_lumea_access_your_camera);
String dialogDesc = getResources().getString(R.string.com_philips_lumea_in_order_use_camera) + "\n" + "\n" + getResources().getString(R.string.com_philips_lumea_go_to_setting_to_change_bar_code);
onRecievingError(dialogTitle, dialogDesc);
}
@Override public void onPermissionGranted() {
boolean autoFocus = true;
boolean useFlash = false;
createCameraSource(autoFocus, useFlash);
}
});
}
private void requestCameraPermission() {
requestPermissions(
new String[]{Manifest.permission.CAMERA},
RC_HANDLE_CAMERA_PERM );
}
@Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == RC_HANDLE_CAMERA_PERM && grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "Camera permission granted - initialize the camera source");
// we have permission, so create the camerasource boolean autoFocus = true;
boolean useFlash = false;
createCameraSource(autoFocus, useFlash);
}
}
/** * Creates and starts the camera. Note that this uses a higher resolution in comparison * to other detection examples to enable the barcode detector to detect small barcodes * at long distances. * <p>
* Suppressing InlinedApi since there is a check that the minimum version is met before using * the constant. */ @SuppressLint("InlinedApi")
private void createCameraSource(boolean autoFocus, boolean useFlash) {
Context context = getApplicationContext();
// A barcode detector is created to track barcodes. An associated multi-processor instance // is set to receive the barcode detection results, track the barcodes, and maintain // graphics for each barcode on screen. The factory is used by the multi-processor to // create a separate tracker instance for each barcode. BarcodeDetector barcodeDetector = new BarcodeDetector.Builder(getActivity()).build();
BarcodeTrackerFactory barcodeFactory = new BarcodeTrackerFactory(null, this);
barcodeDetector.setProcessor(
new MultiProcessor.Builder<>(barcodeFactory).build());
if (!barcodeDetector.isOperational()) {
// Note: The first time that an app using the barcode or face API is installed on a // device, GMS will download a native libraries to the device in order to do detection. // Usually this completes before the app is run for the first time. But if that // download has not yet completed, then the above call will not detect any barcodes // and/or faces. // // isOperational() can be used to check if the required native libraries are currently // available. The detectors will automatically become operational once the library // downloads complete on device. Log.w(TAG, "Detector dependencies are not yet available.");
// Check for low storage. If there is low storage, the native library will not be // downloaded, so detection will not become operational. IntentFilter lowstorageFilter = new IntentFilter(Intent.ACTION_DEVICE_STORAGE_LOW);
boolean hasLowStorage = getActivity().registerReceiver(null, lowstorageFilter) != null;
if (hasLowStorage) {
Log.w(TAG, "Low storage error");
}
}
// Creates and starts the camera. Note that this uses a higher resolution in comparison // to other detection examples to enable the barcode detector to detect small barcodes // at long distances.
DisplayMetrics displayMetrics = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
int height = displayMetrics.heightPixels;
int width = displayMetrics.widthPixels;
CameraSource.Builder builder = new CameraSource.Builder(getActivity(), barcodeDetector)
.setFacing(CameraSource.CAMERA_FACING_BACK)
.setRequestedPreviewSize(width, height)
.setRequestedFps(15.0f);
// make sure that auto focus is an available option 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();
}
/** * Restarts the camera. */ @Override public void onResume() {
super.onResume();
startCameraSource();
}
/** * Stops the camera. */ @Override public void onPause() {
super.onPause();
if (mPreview != null) {
mPreview.stop();
}
}
@Override public void onStart() {
super.onStart();
// read parameters from the intent used to launch the activity. boolean autoFocus = true;
boolean useFlash = false;
// Check for the camera permission before accessing the camera. If the // permission is not granted yet, request permission. int rc = ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA);
if (rc == PackageManager.PERMISSION_GRANTED) {
createCameraSource(autoFocus, useFlash);
} else {
checkCameraPermission();
}
}
@Override public void onStop() {
super.onStop();
if (mPreview != null) {
mPreview.stop();
}
if (customDialogFragment != null) {
customDialogFragment.dismissAllowingStateLoss();
customDialogFragment = null;
}
}
/** * Releases the resources associated with the camera source, the associated detectors, and the * rest of the processing pipeline. */ @Override public void onDestroy() {
super.onDestroy();
if (customDialogFragment != null) {
customDialogFragment.dismiss();
customDialogFragment = null;
}
if (handler != null)
handler.removeCallbacks(runnable);
if (mPreview != null) {
mPreview.release();
}
}
/** * Starts or restarts the camera source, if it exists. If the camera source doesn't exist yet * (e.g., because onResume was called before the camera source was created), this will be called * again when the camera source is created. */ private void startCameraSource() throws SecurityException {
// check that the device has play services available. int code = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(
getActivity());
if (code != ConnectionResult.SUCCESS) {
Dialog dlg =
GoogleApiAvailability.getInstance().getErrorDialog(getActivity(), code, RC_HANDLE_GMS);
dlg.show();
}
if (mCameraSource != null) {
try {
if (mPreview != null)
mPreview.start(mCameraSource, null);
} catch (IOException e) {
Log.e(TAG, "Unable to start camera source.", e);
mCameraSource.release();
mCameraSource = null;
}
}
}
@Override public void onClick(View v) {
switch (v.getId()) {
case R.id.ivBarCodeBackButton:
moveToImprovedDeviceSelectionFragment();
break;
case R.id.rlManualEntryBar:
if (tvBarCodeScanner.getText().equals(getResources().getString(R.string.com_philips_lumea_submit))) {
onSubmittingEan();
} else {
onClickOfManualEntryMethod();
}
break;
}
}
private void moveToImprovedDeviceSelectionFragment() {
getStackActivity().getFragmentStack().navigateBack();
}
private void onClickOfManualEntryMethod() {
rlGiveYourBarCodeNumber.setVisibility(View.VISIBLE);
rlManualEntryBar.setVisibility(View.GONE);
if (mCameraSource != null)
mCameraSource.stop();
preview.setVisibility(View.GONE);
tvManualEntry.requestFocus();
tvManualEntry.addTextChangedListener(new TextWatcher() {
@Override public void afterTextChanged(Editable s) {
}
@Override public void beforeTextChanged(CharSequence s, int start,
int count, int after) {
}
@Override public void onTextChanged(CharSequence s, int start,
int before, int count) {
if (s.length() != 0) {
rlManualEntryBar.setVisibility(View.VISIBLE);
tvBarCodeScanner.setText(getResources().getString(R.string.com_philips_lumea_submit));
tvBarCodeScanner.setGravity(Gravity.CENTER_HORIZONTAL);
} else {
rlManualEntryBar.setVisibility(View.GONE);
}
}
});
InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
}
private void onSubmittingEan() {
String eanNumber = tvManualEntry.getText().toString();
if (eanNumber != null && ApplicationData.getInstance().getCtnListWithEan().containsKey(eanNumber)) {
tvManualEntry.setText("");
Bundle bundle = getArguments();
if (bundle == null) bundle = new Bundle();
bundle.putString(ImprovedSelectionDetailFragment.BAR_CODE_DATA, eanNumber);
FragmentHelper.startFragment(getStackActivity(), ImprovedSelectionDetailFragment.TAG, bundle, 0, true);
} else {
String errorDesc = getResources().getString(R.string.com_philips_lumea_please_check_ifyou_have_entered) + "\n" + "\n" + getResources().getString(R.string.com_philips_lumea_please_go_back_to_overview);
onRecievingError("com_philips_lumea_bar_not_found", errorDesc);
}
}
int attemptToDetectBarCode = 0;
Handler handler = new Handler();
boolean isBarCodeDetected = false;
Runnable runnable = new Runnable() {
@Override public void run() {
if (!isBarCodeDetected)
onRecievingError("com_philips_lumea_bar_not_found", getResources().getString(R.string.com_philips_lumea_please_go_back_to_overview));
}
};
@Override public void onBarcodeDetected(Barcode barcode) {
if (barcode != null && ApplicationData.getInstance().getCtnListWithEan().containsKey(barcode.displayValue)) {
isBarCodeDetected = true;
System.out.println(" Barcode display value : " + barcode.displayValue);
Bundle bundle = getArguments();
if (bundle == null) bundle = new Bundle();
bundle.putString(ImprovedSelectionDetailFragment.BAR_CODE_DATA, barcode.displayValue);
FragmentHelper.startFragment(getStackActivity(), ImprovedSelectionDetailFragment.TAG, bundle, 0, true);
} else {
// keep 5 attempt to identify the correct bar code if (attemptToDetectBarCode == 0) {
attemptToDetectBarCode = 1;
handler.postDelayed(runnable, 2000);
}
}
}
private void onRecievingError(String dialogTitle, String string) {
if (customDialogFragment != null && customDialogFragment.getDialog() != null && customDialogFragment.getDialog().isShowing())
return;
customDialogFragment = CustomDialogFragment.createCustomDialog(
dialogTitle,//Dialog Title string,//Dialog Description "com_philips_lumea_okay",//Left button text "com_philips_lumea_okay",//right button text true,//'true' if its SingleButton Dialog this, false, -1);//Dialog button event listener customDialogFragment.show(getChildFragmentManager(), "dialog");
}
@Override public void onDialogButtonClicked(ACTION action, int dialogID) {
if (customDialogFragment != null)
customDialogFragment.dismiss();
customDialogFragment = null;
attemptToDetectBarCode = 0;
}
}
Comments
Post a Comment