wjc
2023-06-06 5308d04e20f3dca6d56ccc3e2b460374540716a6
app/src/main/java/com/hdl/photovoltaic/ui/device/FastScanActivity.java
@@ -1,17 +1,78 @@
package com.hdl.photovoltaic.ui.device;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.content.res.AppCompatResources;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Rect;
import android.hardware.Camera;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.Toast;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.ChecksumException;
import com.google.zxing.DecodeHintType;
import com.google.zxing.FormatException;
import com.google.zxing.NotFoundException;
import com.google.zxing.Result;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.QRCodeReader;
import com.hdl.photovoltaic.R;
import com.hdl.photovoltaic.base.CustomBaseActivity;
import com.hdl.photovoltaic.databinding.ActivityFastScanBinding;
import com.zxing.IZxingActivity;
import com.zxing.camera.CameraManager;
import com.zxing.decode.DecodeThread;
import com.zxing.decode.RGBLuminanceSource;
import com.zxing.utils.BeepManager;
import com.zxing.utils.CaptureActivityHandler;
import com.zxing.utils.InactivityTimer;
public class FastScanActivity extends CustomBaseActivity {
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.Hashtable;
public class FastScanActivity extends CustomBaseActivity implements IZxingActivity, SurfaceHolder.Callback {
    private static final String TAG = com.zxing.qrcode.CaptureActivity.class.getSimpleName();
    private final int REQUEST_CODE = 33;
    private CameraManager cameraManager;
    private CaptureActivityHandler handler;
    private InactivityTimer inactivityTimer;
    private BeepManager beepManager;
    private SurfaceView scanPreview = null;
    private RelativeLayout scanContainer;
    private RelativeLayout scanCropView;
    private Rect mCropRect = null;
    private boolean isHasSurface = false;
    private ActivityFastScanBinding viewBinding;
    @Override
    public Handler getHandler() {
        return handler;
    }
    @Override
    public void drawViewfinder() {
    }
    @Override
    public CameraManager getCameraManager() {
        return cameraManager;
    }
    @Override
    public Object getContentView() {
@@ -21,6 +82,352 @@
    @Override
    public void onBindView(Bundle savedInstanceState) {
//        Window window = getWindow();
//        window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
//        //设置根视图
//        View mContentView = LayoutInflater.from(this).inflate(R.layout.activity_new_capture, null);
//        setContentView(mContentView);
        //初始化
        initView(savedInstanceState);
        //初始化界面监听器
        initEvent();
    }
    private void initView(Bundle savedInstanceState) {
        scanPreview = findViewById(R.id.new_capture_preview);
        scanContainer = findViewById(R.id.new_capture_rl);
        scanCropView = findViewById(R.id.new_capture_crop_view);
        ImageView scanLine = findViewById(R.id.new_capture_scan_line);
        inactivityTimer = new InactivityTimer(this);
        beepManager = new BeepManager(this);
        TranslateAnimation animation = new TranslateAnimation(Animation.RELATIVE_TO_PARENT, 0.0f, Animation
                .RELATIVE_TO_PARENT, 0.0f, Animation.RELATIVE_TO_PARENT, 0.0f, Animation.RELATIVE_TO_PARENT,
                0.9f);
        animation.setDuration(2000);
        animation.setRepeatCount(-1);
        animation.setRepeatMode(Animation.RESTART);
        scanLine.startAnimation(animation);
    }
    private void initEvent() {
        viewBinding.newTopBackBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });
        viewBinding.newTopMoreBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //跳到入网
            }
        });
        viewBinding.newLightIv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                v.setSelected(!v.isSelected());
                if (v.isSelected()) {
                    viewBinding.newLightIv.setImageDrawable(AppCompatResources.getDrawable(FastScanActivity.this, com.zxing.R.drawable.fast_scan_light_open));
                } else {
                    viewBinding.newLightIv.setImageDrawable(AppCompatResources.getDrawable(FastScanActivity.this, com.zxing.R.drawable.fast_scan_light_close));
                }
                flashLightOnOrOff();
            }
        });
    }
    public void enterGallery() {
        // 进入图库
        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        intent.setType("image/*");
        intent.putExtra("return-data", true);
        startActivityForResult(intent, REQUEST_CODE);
    }
    @Override
    protected void onResume() {
        super.onResume();
        cameraManager = new CameraManager(getApplication());
        handler = null;
        if (isHasSurface) {
            initCamera(scanPreview.getHolder());
        } else {
            scanPreview.getHolder().addCallback(this);
        }
        inactivityTimer.onResume();
    }
    @Override
    protected void onPause() {
        if (handler != null) {
            handler.quitSynchronously();
            handler = null;
        }
        inactivityTimer.onPause();
        beepManager.close();
        cameraManager.closeDriver();
        if (!isHasSurface) {
            scanPreview.getHolder().removeCallback(this);
        }
        super.onPause();
    }
    @Override
    protected void onDestroy() {
        inactivityTimer.shutdown();
        super.onDestroy();
    }
    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        if (holder == null) {
            Log.d(TAG, "*** WARNING *** surfaceCreated() gave us a null surface!");
        }
        if (!isHasSurface) {
            isHasSurface = true;
            initCamera(holder);
        }
    }
    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        isHasSurface = false;
    }
    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    }
}
    /**
     * A valid barcode has been found, so give an indication of success and show
     * the results.
     *
     * @param rawResult The contents of the barcode.
     * @param bundle    The extras
     */
    @Override
    public void handleDecode(Result rawResult, Bundle bundle) {
        inactivityTimer.onActivity();
        beepManager.playBeepSoundAndVibrate();
        doProcess(rawResult.getText());
        restartPreviewAfterDelay(3000);
    }
    private void initCamera(SurfaceHolder surfaceHolder) {
        if (surfaceHolder == null) {
            throw new IllegalStateException("No SurfaceHolder provided");
        }
        if (cameraManager.isOpen()) {
            Log.w(TAG, "initCamera() while already open -- late SurfaceView callback?");
            return;
        }
        try {
            cameraManager.openDriver(surfaceHolder);
            // Creating the handler starts the preview, which can also throw a
            // RuntimeException.
            if (handler == null) {
                handler = new CaptureActivityHandler(this, cameraManager, DecodeThread.ALL_MODE);
            }
            initCrop();
        } catch (IOException ioe) {
            Log.w(TAG, ioe);
            Toast.makeText(this, com.zxing.R.string.capture_no_camera, Toast.LENGTH_SHORT).show();
            finish();
        } catch (RuntimeException e) {
            Log.w(TAG, "Unexpected error initializing camera", e);
            Toast.makeText(this, com.zxing.R.string.capture_no_camera, Toast.LENGTH_SHORT).show();
            finish();
        }
    }
    public void restartPreviewAfterDelay(long delayMS) {
        if (handler != null) {
            handler.sendEmptyMessageDelayed(com.zxing.R.id.restart_preview, delayMS);
        }
    }
    @Override
    public Rect getCropRect() {
        return mCropRect;
    }
    /**
     * 初始化截取的矩形区域
     */
    private void initCrop() {
        int cameraWidth = cameraManager.getCameraResolution().y;
        int cameraHeight = cameraManager.getCameraResolution().x;
        /** 获取布局中扫描框的位置信息 */
        int[] location = new int[2];
        scanCropView.getLocationInWindow(location);
        int cropLeft = location[0];
        int cropTop = location[1] - getStatusBarHeight();
        int cropWidth = scanCropView.getWidth();
        int cropHeight = scanCropView.getHeight();
        /** 获取布局容器的宽高 */
        int containerWidth = scanContainer.getWidth();
        int containerHeight = scanContainer.getHeight();
        /** 计算最终截取的矩形的左上角顶点x坐标 */
        int x = cropLeft * cameraWidth / containerWidth;
        /** 计算最终截取的矩形的左上角顶点y坐标 */
        int y = cropTop * cameraHeight / containerHeight;
        /** 计算最终截取的矩形的宽度 */
        int width = cropWidth * cameraWidth / containerWidth;
        /** 计算最终截取的矩形的高度 */
        int height = cropHeight * cameraHeight / containerHeight;
        /** 生成最终的截取的矩形 */
        mCropRect = new Rect(x, y, width + x, height + y);
    }
    private int getStatusBarHeight() {
        try {
            Class<?> c = Class.forName("com.android.internal.R$dimen");
            Object obj = c.newInstance();
            Field field = c.getField("status_bar_height");
            int x = Integer.parseInt(field.get(obj).toString());
            return getResources().getDimensionPixelSize(x);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0;
    }
    private void doProcess(String result) {
        Log.d("panlili", "scanResult: " + result);
        /*if (!DeviceHelper.getNetworkState()) {
            Toast.makeText(this, R.string.capture_no_network, Toast.LENGTH_SHORT).show();
            return;
        }*/
        if (TextUtils.isEmpty(result)) {
            Toast.makeText(this, com.zxing.R.string.capture_no_result, Toast.LENGTH_SHORT).show();
        } else {
            Intent intent = new Intent();
            intent.putExtra("data", result);
            setResult(RESULT_OK, intent);
            finish();
        }
    }
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CODE && resultCode == RESULT_OK && data != null) {
            Uri originalUri = data.getData();
            if (originalUri != null) {
                String path = originalUri.getPath();
                String[] proj = {MediaStore.Images.Media.DATA};
                Cursor cursor = getContentResolver().query(originalUri, proj, null, null, null);
                if (cursor != null) {
                    int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
                    cursor.moveToFirst();
                    path = cursor.getString(column_index);
                    cursor.close();
                }
                if (!TextUtils.isEmpty(path)) {
                    handleQRCodeFormPhoto(path);
                } else {
                    Toast.makeText(this, "图片已损坏,请重新选择!", Toast.LENGTH_SHORT).show();
                }
            }
        }
    }
    /**
     * 解析图库选择的二维码
     */
    public void handleQRCodeFormPhoto(final String filePath) {
        Thread dealThread = new Thread(new Runnable() {
            @Override
            public void run() {
                Hashtable<DecodeHintType, String> hints = new Hashtable<>();
                hints.put(DecodeHintType.CHARACTER_SET, "utf-8");
                RGBLuminanceSource source = null;
                try {
                    source = new RGBLuminanceSource(filePath);
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }
                BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(source));
                QRCodeReader reader = new QRCodeReader();
                Result result;
                try {
                    result = reader.decode(binaryBitmap, hints);
                    if (!TextUtils.isEmpty(result.getText())) {
                        dealUIInfo(result.getText());
                    } else {
                        dealUIInfo(null);
                    }
                } catch (NotFoundException | ChecksumException | FormatException e) {
                    dealUIInfo(null);
                    e.printStackTrace();
                }
            }
        });
        dealThread.start();
    }
    private void dealUIInfo(final Object progressInfo) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (progressInfo == null) {
                    Toast.makeText(FastScanActivity.this, com.zxing.R.string.capture_no_result2, Toast.LENGTH_SHORT).show();
                } else {
                    doProcess(progressInfo.toString());
                }
            }
        });
    }
    /**
     * 闪光灯开启或者关闭
     */
    private void flashLightOnOrOff() {
//
        android.hardware.Camera camera = cameraManager.getCamera();
        if (camera == null) {
            return;
        }
        android.hardware.Camera.Parameters parameters = camera.getParameters();
//      判断闪光灯当前状态
        if (Camera.Parameters.FLASH_MODE_OFF.equals(parameters.getFlashMode())) {
            onLight(camera, parameters);
        } else if (Camera.Parameters.FLASH_MODE_TORCH.equals(parameters.getFlashMode())) {
            offLight(camera, parameters);
        }
    }
    private void onLight(android.hardware.Camera camera, Camera.Parameters parameters) {
        parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
        camera.setParameters(parameters);
    }
    private void offLight(android.hardware.Camera camera, Camera.Parameters parameters) {
        parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
        camera.setParameters(parameters);
    }
}