package com.geogle.zxing.activity; import android.app.ProgressDialog; import android.content.Intent; import android.content.res.AssetFileDescriptor; import android.graphics.Bitmap; import android.media.AudioManager; import android.media.MediaPlayer; import android.media.MediaPlayer.OnCompletionListener; import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.os.Vibrator; import android.text.TextUtils; import android.view.SurfaceHolder; import android.view.SurfaceHolder.Callback; import android.view.SurfaceView; import android.view.View; import android.widget.Button; import android.widget.ImageButton; import android.widget.Toast; import androidx.appcompat.app.AppCompatActivity; import com.google.zxing.BarcodeFormat; 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.geogle.zxing.camera.CameraManager; import com.google.zxing.common.HybridBinarizer; import com.geogle.zxing.decoding.InactivityTimer; import com.geogle.zxing.decoding.RGBLuminanceSource; import com.google.zxing.qrcode.QRCodeReader; import com.geogle.zxing.view.ViewfinderView; import java.io.IOException; import java.util.Hashtable; import java.util.Vector; import com.geogle.zxing.decoding.CaptureActivityHandler; import edu.hzuapps.androidlabs.R; /** * Initial the camera * * @author Ryan.Tang */ public class CaptureActivity extends AppCompatActivity implements Callback { private static final int REQUEST_CODE_SCAN_GALLERY = 100; private CaptureActivityHandler handler; private ViewfinderView viewfinderView; private ImageButton back; private ImageButton btnFlash; private Button btnAlbum; // 相册 private boolean isFlashOn = false; private boolean hasSurface; private Vector decodeFormats; private String characterSet; private InactivityTimer inactivityTimer; private MediaPlayer mediaPlayer; private boolean playBeep; private static final float BEEP_VOLUME = 0.10f; private boolean vibrate; private ProgressDialog mProgress; private String photo_path; private Bitmap scanBitmap; // private Button cancelScanButton; /** * Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_scanner); //ViewUtil.addTopView(getApplicationContext(), this, R.string.scan_card); CameraManager.init(getApplication()); viewfinderView = (ViewfinderView) findViewById(R.id.viewfinder_content); back = (ImageButton) findViewById(R.id.btn_back); back.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { finish(); } }); btnFlash = (ImageButton) findViewById(R.id.btn_flash); btnFlash.setOnClickListener(flashListener); btnAlbum = (Button) findViewById(R.id.btn_album); btnAlbum.setOnClickListener(albumOnClick); // cancelScanButton = (Button) this.findViewById(R.id.btn_cancel_scan); hasSurface = false; inactivityTimer = new InactivityTimer(this); } private View.OnClickListener albumOnClick = new View.OnClickListener() { @Override public void onClick(View view) { //打开手机中的相册 Intent innerIntent = new Intent(Intent.ACTION_GET_CONTENT); //"android.intent.action.GET_CONTENT" innerIntent.setType("image/*"); startActivityForResult(innerIntent, REQUEST_CODE_SCAN_GALLERY); } }; @Override protected void onActivityResult(final int requestCode, int resultCode, Intent data) { if (resultCode==RESULT_OK) { switch (requestCode) { case REQUEST_CODE_SCAN_GALLERY: handleAlbumPic(data); break; } } super.onActivityResult(requestCode, resultCode, data); } /** * 处理选择的图片 * @param data */ private void handleAlbumPic(Intent data) { //获取选中图片的路径 final Uri uri = data.getData(); mProgress = new ProgressDialog(CaptureActivity.this); mProgress.setMessage("正在扫描..."); mProgress.setCancelable(false); mProgress.show(); runOnUiThread(new Runnable() { @Override public void run() { Result result = scanningImage(uri); mProgress.dismiss(); if (result != null) { Intent resultIntent = new Intent(); Bundle bundle = new Bundle(); bundle.putString(com.dommy.qrcode.util.Constant.INTENT_EXTRA_KEY_QR_SCAN ,result.getText()); resultIntent.putExtras(bundle); CaptureActivity.this.setResult(RESULT_OK, resultIntent); finish(); } else { Toast.makeText(CaptureActivity.this, "识别失败", Toast.LENGTH_SHORT).show(); } } }); } /** * 扫描二维码图片的方法 * @param uri * @return */ public Result scanningImage(Uri uri) { if (uri == null) { return null; } Hashtable hints = new Hashtable<>(); hints.put(DecodeHintType.CHARACTER_SET, "UTF8"); //设置二维码内容的编码 scanBitmap = com.dommy.qrcode.util.BitmapUtil.decodeUri(this, uri, 500, 500); RGBLuminanceSource source = new RGBLuminanceSource(scanBitmap); BinaryBitmap bitmap1 = new BinaryBitmap(new HybridBinarizer(source)); QRCodeReader reader = new QRCodeReader(); try { return reader.decode(bitmap1, hints); } catch (NotFoundException e) { e.printStackTrace(); } catch (ChecksumException e) { e.printStackTrace(); } catch (FormatException e) { e.printStackTrace(); } return null; } @Override protected void onResume() { super.onResume(); SurfaceView surfaceView = (SurfaceView) findViewById(R.id.scanner_view); SurfaceHolder surfaceHolder = surfaceView.getHolder(); if (hasSurface) { initCamera(surfaceHolder); } else { surfaceHolder.addCallback(this); surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); } decodeFormats = null; characterSet = null; playBeep = true; AudioManager audioService = (AudioManager) getSystemService(AUDIO_SERVICE); if (audioService.getRingerMode() != AudioManager.RINGER_MODE_NORMAL) { playBeep = false; } initBeepSound(); vibrate = true; //quit the scan view // cancelScanButton.setOnClickListener(new OnClickListener() { // // @Override // public void onClick(View v) { // CaptureActivity.this.finish(); // } // }); } @Override protected void onPause() { super.onPause(); if (handler != null) { handler.quitSynchronously(); handler = null; } CameraManager.get().closeDriver(); } @Override protected void onDestroy() { inactivityTimer.shutdown(); super.onDestroy(); } /** * Handler scan result * * @param result * @param barcode */ public void handleDecode(Result result, Bitmap barcode) { inactivityTimer.onActivity(); playBeepSoundAndVibrate(); String resultString = result.getText(); //FIXME if (TextUtils.isEmpty(resultString)) { Toast.makeText(CaptureActivity.this, "Scan failed!", Toast.LENGTH_SHORT).show(); } else { Intent resultIntent = new Intent(); Bundle bundle = new Bundle(); bundle.putString(com.dommy.qrcode.util.Constant.INTENT_EXTRA_KEY_QR_SCAN, resultString); System.out.println("sssssssssssssssss scan 0 = " + resultString); // 不能使用Intent传递大于40kb的bitmap,可以使用一个单例对象存储这个bitmap // bundle.putParcelable("bitmap", barcode); // Logger.d("saomiao",resultString); resultIntent.putExtras(bundle); this.setResult(RESULT_OK, resultIntent); } CaptureActivity.this.finish(); } private void initCamera(SurfaceHolder surfaceHolder) { try { CameraManager.get().openDriver(surfaceHolder); } catch (IOException ioe) { return; } catch (RuntimeException e) { return; } if (handler == null) { handler = new CaptureActivityHandler(this, decodeFormats, characterSet); } } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceCreated(SurfaceHolder holder) { if (!hasSurface) { hasSurface = true; initCamera(holder); } } @Override public void surfaceDestroyed(SurfaceHolder holder) { hasSurface = false; } public ViewfinderView getViewfinderView() { return viewfinderView; } public Handler getHandler() { return handler; } public void drawViewfinder() { viewfinderView.drawViewfinder(); } private void initBeepSound() { if (playBeep && mediaPlayer == null) { // The volume on STREAM_SYSTEM is not adjustable, and users found it // too loud, // so we now play on the music stream. setVolumeControlStream(AudioManager.STREAM_MUSIC); mediaPlayer = new MediaPlayer(); mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mediaPlayer.setOnCompletionListener(beepListener); AssetFileDescriptor file = getResources().openRawResourceFd( R.raw.beep); try { mediaPlayer.setDataSource(file.getFileDescriptor(), file.getStartOffset(), file.getLength()); file.close(); mediaPlayer.setVolume(BEEP_VOLUME, BEEP_VOLUME); mediaPlayer.prepare(); } catch (IOException e) { mediaPlayer = null; } } } private static final long VIBRATE_DURATION = 200L; private void playBeepSoundAndVibrate() { if (playBeep && mediaPlayer != null) { mediaPlayer.start(); } if (vibrate) { Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE); vibrator.vibrate(VIBRATE_DURATION); } } /** * When the beep has finished playing, rewind to queue up another one. */ private final OnCompletionListener beepListener = new OnCompletionListener() { public void onCompletion(MediaPlayer mediaPlayer) { mediaPlayer.seekTo(0); } }; /** * 闪光灯开关按钮 */ private View.OnClickListener flashListener = new View.OnClickListener() { @Override public void onClick(View view) { try { boolean isSuccess = CameraManager.get().setFlashLight(!isFlashOn); if(!isSuccess){ Toast.makeText(CaptureActivity.this, "暂时无法开启闪光灯", Toast.LENGTH_SHORT).show(); return; } if (isFlashOn) { // 关闭闪光灯 btnFlash.setImageResource(R.drawable.flash_off); isFlashOn = false; } else { // 开启闪光灯 btnFlash.setImageResource(R.drawable.flash_on); isFlashOn = true; } }catch (Exception e){ e.printStackTrace(); } } }; }