package net.coding.program.login.auth;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.PointF;
import android.graphics.Rect;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import com.dlazaro66.qrcodereaderview.QRCodeReaderView;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.RGBLuminanceSource;
import com.google.zxing.Result;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.QRCodeReader;
import net.coding.program.R;
import net.coding.program.common.htmltext.URLSpanNoUnderline;
import java.io.InputStream;
public class QRScanActivity extends AppCompatActivity implements QRCodeReaderView.OnQRCodeReadListener {
// 说明是由tip界面跳转过来的
// public static final String EXTRA_TIP = "EXTRA_TIP";
public static final String EXTRA_OPEN_AUTH_LIST = "EXTRA_OPEN_AUTH_LIST"; // true 表示需要打开二次验证列表
private QRCodeReaderView qrCodeView;
private final int RESULT_REQUEST_PHOTO = 1;
private boolean openAuthList = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.activity_main1);
ActionBar supportActionBar = getSupportActionBar();
if (supportActionBar != null) {
supportActionBar.setDisplayHomeAsUpEnabled(true);
}
openAuthList = getIntent().getBooleanExtra(EXTRA_OPEN_AUTH_LIST, true);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.qrscan, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
return true;
case R.id.action_photo:
photo();
return true;
}
return super.onOptionsItemSelected(item);
}
View codeViewRoot;
@Override
protected void onResume() {
super.onResume();
codeViewRoot = getLayoutInflater().inflate(R.layout.activity_main1, null, false);
((ViewGroup) findViewById(android.R.id.content)).addView(codeViewRoot);
qrCodeView = (QRCodeReaderView) findViewById(R.id.qrdecoderview);
qrCodeView.setOnQRCodeReadListener(this);
qrCodeView.getCameraManager().startPreview();
}
private void photo() {
Intent i = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, RESULT_REQUEST_PHOTO);
}
@Override
protected void onPause() {
super.onPause();
if (codeViewRoot != null) {
qrCodeView.getCameraManager().stopPreview();
qrCodeView = null;
((ViewGroup) findViewById(android.R.id.content)).removeView(codeViewRoot);
codeViewRoot = null;
}
}
boolean enableScan = true;
@Override
public void onQRCodeRead(String s, PointF[] pointFs) {
Log.d("", "scan " + s);
if (!enableScan) {
return;
}
// 可能调用多次,所以做个检测
if (isFinishing()) {
return;
}
enableScan = false;
if (!AuthInfo.isAuthUrl(s)) {
Uri uri = Uri.parse(s);
String host = uri.getHost();
if (host.toLowerCase().endsWith("coding.net")) { // coding.net 结尾的使用内部浏览器打开, 比如 mart.coding.net
URLSpanNoUnderline.openActivityByUri(this, s, false, true, true);
finish();
} else {
new AlertDialog.Builder(QRScanActivity.this)
.setTitle("打开外部链接")
.setMessage(s)
.setPositiveButton("确定", (dialog, which) -> {
try {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(s));
startActivity(intent);
finish();
} catch (Exception e) {
Toast.makeText(QRScanActivity.this, "用浏览器打开失败", Toast.LENGTH_LONG).show();
}
})
.setNegativeButton("取消", null)
.setOnDismissListener(dialog -> enableScan = true)
.show();
}
} else {
// if (getIntent().getBooleanExtra(EXTRA_TIP, false)) {
if (openAuthList) {
Intent intent = new Intent(this, AuthListActivity.class);
intent.putExtra("data", s);
startActivity(intent);
}
// } else {
Intent intentResult = new Intent();
intentResult.putExtra("data", s);
setResult(RESULT_OK, intentResult);
// }
finish();
}
}
private ProgressDialog mProgressDialog;
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == RESULT_REQUEST_PHOTO) {
if (resultCode == Activity.RESULT_OK) {
if (data != null) {
Uri fileUri = data.getData();
if (mProgressDialog == null) {
mProgressDialog = new ProgressDialog(this);
mProgressDialog.setMessage("扫描中...");
}
mProgressDialog.show();
new ScanPhotoTask().execute(fileUri);
}
}
}
}
@Override
public void cameraNotFound() {
}
@Override
public void QRCodeNotFoundOnCamImage() {
}
class ScanPhotoTask extends AsyncTask<Uri, Void, Result> {
String TAG = "readPhot";
@Override
protected Result doInBackground(Uri... params) {
if (params == null || params.length != 1) {
return null;
}
try {
InputStream inputStream = QRScanActivity.this.getContentResolver().openInputStream(params[0]);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
Rect padding = new Rect(0, 0, 0, 0);
BitmapFactory.decodeStream(inputStream, null, options);
inputStream.close();
int minLength = Math.min(options.outWidth, options.outHeight);
int MAX = 512; // 图片短边不超过 512
if (minLength > MAX) {
options.inSampleSize = minLength / MAX;
}
options.inJustDecodeBounds = false;
// 流打开后只能用一次, 需要重新获取
inputStream = QRScanActivity.this.getContentResolver().openInputStream(params[0]);
// 对图片裁剪后再扫码, 否则花的时间太长
Bitmap bitmap = BitmapFactory.decodeStream(inputStream, null, options);
if (bitmap == null) {
return null;
}
int width = bitmap.getWidth(), height = bitmap.getHeight();
int[] pixels = new int[width * height];
bitmap.getPixels(pixels, 0, width, 0, 0, width, height);
bitmap.recycle();
RGBLuminanceSource source = new RGBLuminanceSource(width, height, pixels);
BinaryBitmap bBitmap = new BinaryBitmap(new HybridBinarizer(source));
QRCodeReader reader = new QRCodeReader();
Result result = reader.decode(bBitmap);
return result;
} catch (Exception e) {
Log.e(TAG, "can not open file", e);
return null;
}
}
@Override
protected void onPostExecute(Result result) {
super.onPostExecute(result);
if (mProgressDialog != null) {
mProgressDialog.hide();
}
if (result == null) {
new AlertDialog.Builder(QRScanActivity.this)
.setTitle("提示")
.setMessage("未发现二维码")
.setPositiveButton("确定", null)
.show();
return;
}
onQRCodeRead(result.getText(), null);
}
}
}