package com.google.zxing;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
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.provider.MediaStore;
import android.util.Log;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.Window;
import android.widget.Toast;
import com.google.zxing.camera.CameraManager;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.decoding.CaptureActivityHandler;
import com.google.zxing.decoding.InactivityTimer;
import com.google.zxing.qrcode.QRCodeReader;
import com.google.zxing.view.ViewfinderView;
import java.io.IOException;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;
import cn.darkal.networkdiagnosis.R;
/**
* Initial the camera
*
* @author Ryan.Tang
*/
public class QrCodeScanActivity extends Activity implements SurfaceHolder.Callback {
private CameraManager cameraManager;
private CaptureActivityHandler handler;
private ViewfinderView viewfinderView;
private boolean hasSurface;
private Vector<BarcodeFormat> decodeFormats;
private String characterSet;
private InactivityTimer inactivityTimer;
private MediaPlayer mediaPlayer;
private boolean playBeep;
private static final float BEEP_VOLUME = 1.00f;
private boolean vibrate;
private static final int REQUEST_CODE_GALLERY = 0x0708;
public CameraManager getCameraManager() {
return cameraManager;
}
/**
* Called when the activity is first created.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_qr_code_scan);
hasSurface = false;
inactivityTimer = new InactivityTimer(this);
}
private void vibrate(long duration) {
Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
long[] pattern = {
0, duration
};
vibrator.vibrate(pattern, -1);
}
private int getCurrentOrientation() {
int rotation = getWindowManager().getDefaultDisplay().getRotation();
switch (rotation) {
case Surface.ROTATION_0:
case Surface.ROTATION_90:
return ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
default:
return ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
}
}
@Override
protected void onResume() {
super.onResume();
// CameraManager must be initialized here, not in onCreate(). This is
// necessary because we don't
// want to open the camera driver and measure the screen size if we're
// going to show the help on
// first launch. That led to bugs where the scanning rectangle was the
// wrong size and partially
// off screen.
cameraManager = new CameraManager(getApplication());
viewfinderView = (ViewfinderView) findViewById(R.id.viewfinder_view);
viewfinderView.setCameraManager(cameraManager);
handler = null;
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
viewfinderView.setVisibility(View.VISIBLE);
SurfaceView surfaceView = (SurfaceView) findViewById(R.id.preview_view);
SurfaceHolder surfaceHolder = surfaceView.getHolder();
if (hasSurface) {
// The activity was paused but not stopped, so the surface still
// exists. Therefore
// surfaceCreated() won't be called, so init the camera here.
initCamera(surfaceHolder);
} else {
// Install the callback and wait for surfaceCreated() to init the
// camera.
surfaceHolder.addCallback(this);
}
decodeFormats = null;
characterSet = null;
playBeep = true;
AudioManager audioService = (AudioManager) getSystemService(AUDIO_SERVICE);
if (audioService.getRingerMode() != AudioManager.RINGER_MODE_NORMAL) {
playBeep = false;
}
initBeepSound();
vibrate = true;
inactivityTimer.onResume();
}
@Override
protected void onPause() {
if (handler != null) {
handler.quitSynchronously();
handler = null;
}
inactivityTimer.onPause();
cameraManager.closeDriver();
if (!hasSurface) {
SurfaceView surfaceView = (SurfaceView) findViewById(R.id.preview_view);
SurfaceHolder surfaceHolder = surfaceView.getHolder();
surfaceHolder.removeCallback(this);
}
super.onPause();
}
@Override
protected void onDestroy() {
inactivityTimer.shutdown();
super.onDestroy();
}
public void handleDecode(Result result, Bitmap barcode, float scaleFactor) {
inactivityTimer.onActivity();
playBeepSoundAndVibrate();
String url = result.getText();
// 只识别http或者https开头的url
if ((url.startsWith("http://") == false) && (url.startsWith("https://") == false)) {
Toast.makeText(this, "未发现二维码", Toast.LENGTH_SHORT).show();
} else {
Intent intent = new Intent("android.intent.action.VIEW");
intent.setData(Uri.parse("jdhttpmonitor://webview?param=" + Uri.encode("{\"url\":\"" + url + "\"" + ", \"from\":\"app\"" + "}")));
startActivity(intent);
}
// 不管成功还是失败,都关闭二维码扫描窗口
finish();
}
private void initCamera(SurfaceHolder surfaceHolder) {
if (surfaceHolder == null) {
throw new IllegalStateException("No SurfaceHolder provided");
}
if (cameraManager.isOpen()) {
Log.w(QrCodeScanActivity.class.getSimpleName(),
"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) {
Map<DecodeHintType, Object> decodeHints = new EnumMap<DecodeHintType, Object>(
DecodeHintType.class);
handler = new CaptureActivityHandler(this, decodeFormats, decodeHints,
characterSet, cameraManager);
}
} catch (IOException ioe) {
Log.w(QrCodeScanActivity.class.getSimpleName(), ioe);
return;
} catch (RuntimeException e) {
// Barcode Scanner has seen crashes in the wild of this variety:
// java.?lang.?RuntimeException: Fail to connect to camera service
Log.w(QrCodeScanActivity.class.getSimpleName(), "Unexpected error initializing camera",
e);
return;
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
if (holder == null) {
Log.e(QrCodeScanActivity.class.getSimpleName(),
"*** WARNING *** surfaceCreated() gave us a null surface!");
}
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.qrcode_completed);
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);
}
};
public void onGalleryClick(View view) {
// 设定action和miniType
Intent intent = new Intent();
intent.setAction(Intent.ACTION_PICK);
intent.setType("image/*");
// 以需要返回值的模式开启一个Activity
startActivityForResult(intent, REQUEST_CODE_GALLERY);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case REQUEST_CODE_GALLERY:
if (resultCode == -1) {
try {
Uri uri = data.getData();
Bitmap bitmap = MediaStore.Images.Media.getBitmap(
this.getContentResolver(), uri);
int[] pixels = new int[bitmap.getWidth() * bitmap.getHeight()];
bitmap.getPixels(pixels, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(),
bitmap.getHeight());
RGBLuminanceSource rgbLuminanceSource = new RGBLuminanceSource(
bitmap.getWidth(), bitmap.getHeight(), pixels);
BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(
rgbLuminanceSource));
QRCodeReader qrCodeReader = new QRCodeReader();
HashMap<DecodeHintType, String> decodeHintTypeStringHashMap = new HashMap<DecodeHintType, String>();
decodeHintTypeStringHashMap.put(DecodeHintType.CHARACTER_SET, "utf-8");
Result result = qrCodeReader.decode(binaryBitmap,
decodeHintTypeStringHashMap);
String url = result.getText();
playBeepSoundAndVibrate();
Intent intent = new Intent("android.intent.action.VIEW");
intent.setData(Uri.parse("jdhttpmonitor://webview?param=" + Uri.encode("{\"url\":\"" + url + "\"" + ", \"from\":\"app\"" + "}")));
startActivity(intent);
// 启动二级页之后,关闭二维码扫描窗口
finish();
} catch (com.google.zxing.NotFoundException e) {
Toast.makeText(this, "未发现二维码", Toast.LENGTH_SHORT).show();
} catch (com.google.zxing.ChecksumException e) {
Toast.makeText(this, "未发现二维码", Toast.LENGTH_SHORT).show();
} catch (com.google.zxing.FormatException e) {
Toast.makeText(this, "未发现二维码", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
Toast.makeText(this, "未发现二维码", Toast.LENGTH_SHORT).show();
}
}
break;
}
}
}