package com.ghj.scanner;
import android.Manifest;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.hardware.Camera;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.VibrationEffect;
import android.os.Vibrator;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.Toast;
import com.ghj.scanner.barcode.BarcodeGraphic;
import com.ghj.scanner.barcode.BarcodeGraphicTracker;
import com.ghj.scanner.barcode.BarcodeTrackerFactory;
import com.ghj.scanner.barcode.CameraSource;
import com.ghj.scanner.barcode.CameraSourcePreview;
import com.ghj.scanner.barcode.GraphicOverlay;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.android.gms.vision.MultiProcessor;
import com.google.android.gms.vision.barcode.Barcode;
import com.google.android.gms.vision.barcode.BarcodeDetector;
import java.io.IOException;
public class BarcodeActivity extends AppCompatActivity implements BarcodeGraphicTracker.BarcodeUpdateListener {
//permission
final private int PERM_REQUEST_CAMERA = 1000;
//ui
private CameraSource mCameraSource;
private CameraSourcePreview mPreview;
private GraphicOverlay<BarcodeGraphic> mGraphicOverlay;
private FrameLayout boxBarcodeScan;
//상수
final private String MSG_FAIL_PERM = "카메라 권한이 없습니다";
final private String MSG_FAIL_LIB = "라이브러리 구동에 실패했습니다";
final private String MSG_FAIL_CAMERA = "카메라 열기에 실패했습니다";
final private long[] VIBRATE_PATTERN = { 0, 70, 10, 40 }; //진동패턴
//플래그
private boolean isFail = false; //실패여부
private boolean mBarcodeGrant = false;
//진동
Vibrator vibrator;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags( WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView( R.layout.activity_barcode );
mPreview = (CameraSourcePreview)findViewById(R.id.preview);
mGraphicOverlay = (GraphicOverlay<BarcodeGraphic>)findViewById(R.id.graphicOverlay);
boxBarcodeScan = (FrameLayout)findViewById(R.id.boxBarcodeScan);
checkPermission();
if( mBarcodeGrant ) {
startBarcode();
}
vibrator = (Vibrator)getSystemService(VIBRATOR_SERVICE);
}
@Override
protected void onResume() {
super.onResume();
if( !isFail ) {
checkPermission();
if( mBarcodeGrant ) {
restartPreview();
}
else {
requestPermission();
}
}
}
@Override
protected void onPause() {
super.onPause();
if( mPreview != null ) {
mPreview.stop();
}
}
@Override
protected void onDestroy() {
onFinish();
super.onDestroy();
}
//권한 체크
public void checkPermission() {
if(Build.VERSION.SDK_INT > 22) {
if( ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED ) {
mBarcodeGrant = false;
return;
}
}
mBarcodeGrant = true;
}
//권한 요청
public void requestPermission() {
if(Build.VERSION.SDK_INT > 22) {
String[] perm = new String[]{Manifest.permission.CAMERA};
requestPermissions(perm, PERM_REQUEST_CAMERA);
}
}
//구글플레이 체크
public boolean checkGooglePlay() {
int code = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(getApplicationContext());
if (code != ConnectionResult.SUCCESS) {
return false;
}
return true;
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if( requestCode == PERM_REQUEST_CAMERA ) {
if( grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//권한획득 성공
mBarcodeGrant = true;
startBarcode();
}
else {
onFailDialog( MSG_FAIL_PERM );
}
}
}
//바코드 시작
public void startBarcode() {
if( mBarcodeGrant ) {
if( checkGooglePlay() ) {
if( !createCameraSource() ) {
//라이브러리 없음
onFailDialog( MSG_FAIL_LIB );
}
}
else {
//구글플레이 서비스 실패
onFailDialog( MSG_FAIL_LIB );
}
}
}
//카메라 객체 생성
private boolean createCameraSource() {
Context context = getApplicationContext();
boolean autoFocus = true;
boolean useFlash = false;
//모든 바코드 검색
BarcodeDetector barcodeDetector = new BarcodeDetector.Builder(this).build();
BarcodeTrackerFactory barcodeFactory = new BarcodeTrackerFactory(mGraphicOverlay, this);
barcodeDetector.setProcessor(new MultiProcessor.Builder<>(barcodeFactory).build());
//필요한 라이브러리를 다운받아서 사용할 수 있는지 여부
if (!barcodeDetector.isOperational()) {
return false;
}
CameraSource.Builder builder = new CameraSource.Builder(getApplicationContext(), barcodeDetector)
.setFacing( CameraSource.CAMERA_FACING_BACK)
.setRequestedPreviewSize(1920, 1080)
.setRequestedFps(15.0f)
.setFocusMode(autoFocus ? Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE : null)
.setFlashMode(useFlash ? Camera.Parameters.FLASH_MODE_TORCH : null);
mCameraSource = builder.build();
return true;
}
//카메라 프리뷰
private void restartPreview() throws SecurityException {
if (mCameraSource != null) {
try {
mPreview.start(mCameraSource, mGraphicOverlay);
} catch (IOException e) {
e.printStackTrace();
//카메라 열다가 실패
onFailDialog( MSG_FAIL_CAMERA );
}
}
}
//바코드 인식됨
@Override
public void onBarcodeDetected(Barcode barcode) {
try {
if( Build.VERSION.SDK_INT >= 26 )
{
VibrationEffect vibrationEffect = VibrationEffect.createWaveform(VIBRATE_PATTERN, -1);
vibrator.vibrate(vibrationEffect);
}
else
{
vibrator.vibrate(VIBRATE_PATTERN, -1);
}
} catch (Exception e) {
e.printStackTrace();
}
final Barcode result = barcode;
AsyncTask.execute(new Runnable() {
@Override
public void run() {
mPreview.stop();
new Handler(getMainLooper()).postDelayed(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), result.displayValue, Toast.LENGTH_SHORT).show();
Intent intent = new Intent();
intent.putExtra( "BARCODE_NUMBER", result.displayValue);
setResult(RESULT_OK, intent);
onFinish();
finish();
}
}, 1000);
}
});
}
//바코드 해제
public void onFinish() {
if( mPreview != null ) {
mPreview.release();
mPreview = null;
}
if( mCameraSource != null ) {
mCameraSource.release();
mCameraSource = null;
}
}
//바코드 인식 실패 다이얼로그
public void onFailDialog(String message) {
isFail = true;
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(message)
.setPositiveButton("확인", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
onFinish();
finish();
}
});
builder.show();
}
}