permissionsDenied) {
+ Toast.makeText(activity,"摄像头权限被拒绝!",Toast.LENGTH_SHORT).show();
+
+ }
+ }).request();
+
+
+
+ // 绑定图片接口回调函数事件
+ resultCallback = resultCall;
+ }
+
+
+
+ public interface OnScanResultCallback {
+ /**
+ * 处理成功
+ * 多选
+ *
+ * @param result
+ */
+ void onScanSuccess(ScanResult result);
+
+ }
+}
diff --git a/zbarlibary/src/main/java/cn/bertsir/zbar/ScanCallback.java b/zbarlibary/src/main/java/cn/bertsir/zbar/ScanCallback.java
new file mode 100644
index 0000000..fdaacb0
--- /dev/null
+++ b/zbarlibary/src/main/java/cn/bertsir/zbar/ScanCallback.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright © Yan Zhenjie
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package cn.bertsir.zbar;
+
+import cn.bertsir.zbar.Qr.ScanResult;
+
+/**
+ * Scan results callback.
+ */
+public interface ScanCallback {
+
+ /**
+ * 扫描结果回调
+ *
+ */
+ void onScanResult(ScanResult result);
+
+}
diff --git a/zbarlibary/src/main/java/cn/bertsir/zbar/utils/GetPathFromUri.java b/zbarlibary/src/main/java/cn/bertsir/zbar/utils/GetPathFromUri.java
new file mode 100644
index 0000000..bbb2a70
--- /dev/null
+++ b/zbarlibary/src/main/java/cn/bertsir/zbar/utils/GetPathFromUri.java
@@ -0,0 +1,133 @@
+package cn.bertsir.zbar.utils;
+
+import android.annotation.SuppressLint;
+import android.content.ContentUris;
+import android.content.Context;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Environment;
+import android.provider.DocumentsContract;
+import android.provider.MediaStore;
+
+/**
+ * Created by Bert on 2018/9/5.
+ */
+public class GetPathFromUri {
+ @SuppressLint("NewApi")
+ public static String getPath(final Context context, final Uri uri) {
+
+ final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
+
+ // DocumentProvider
+ if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
+ // ExternalStorageProvider
+ if (isExternalStorageDocument(uri)) {
+ final String docId = DocumentsContract.getDocumentId(uri);
+ final String[] split = docId.split(":");
+ final String type = split[0];
+
+ if ("primary".equalsIgnoreCase(type)) {
+ return Environment.getExternalStorageDirectory() + "/" + split[1];
+ }
+
+ // TODO handle non-primary volumes
+ }
+ // DownloadsProvider
+ else if (isDownloadsDocument(uri)) {
+
+ final String id = DocumentsContract.getDocumentId(uri);
+ final Uri contentUri = ContentUris.withAppendedId(
+ Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
+
+ return getDataColumn(context, contentUri, null, null);
+ }
+ // MediaProvider
+ else if (isMediaDocument(uri)) {
+ final String docId = DocumentsContract.getDocumentId(uri);
+ final String[] split = docId.split(":");
+ final String type = split[0];
+
+ Uri contentUri = null;
+ if ("image".equals(type)) {
+ contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
+ } else if ("video".equals(type)) {
+ contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
+ } else if ("audio".equals(type)) {
+ contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
+ }
+
+ final String selection = "_id=?";
+ final String[] selectionArgs = new String[]{split[1]};
+
+ return getDataColumn(context, contentUri, selection, selectionArgs);
+ }
+ }
+ // MediaStore (and general)
+ else if ("content".equalsIgnoreCase(uri.getScheme())) {
+ return getDataColumn(context, uri, null, null);
+ }
+ // File
+ else if ("file".equalsIgnoreCase(uri.getScheme())) {
+ return uri.getPath();
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the value of the data column for this Uri. This is useful for
+ * MediaStore Uris, and other file-based ContentProviders.
+ *
+ * @param context The context.
+ * @param uri The Uri to query.
+ * @param selection (Optional) Filter used in the query.
+ * @param selectionArgs (Optional) Selection arguments used in the query.
+ * @return The value of the _data column, which is typically a file path.
+ */
+ public static String getDataColumn(Context context, Uri uri, String selection,
+ String[] selectionArgs) {
+
+ Cursor cursor = null;
+ final String column = "_data";
+ final String[] projection = {column};
+
+ try {
+ cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
+ null);
+ if (cursor != null && cursor.moveToFirst()) {
+ final int column_index = cursor.getColumnIndexOrThrow(column);
+ return cursor.getString(column_index);
+ }
+ } finally {
+ if (cursor != null)
+ cursor.close();
+ }
+ return null;
+ }
+
+ /**
+ * @param uri The Uri to check.
+ * @return Whether the Uri authority is ExternalStorageProvider.
+ */
+ public static boolean isExternalStorageDocument(Uri uri) {
+ return "com.android.externalstorage.documents".equals(uri.getAuthority());
+ }
+
+ /**
+ * @param uri The Uri to check.
+ * @return Whether the Uri authority is DownloadsProvider.
+ */
+ public static boolean isDownloadsDocument(Uri uri) {
+ return "com.android.providers.downloads.documents".equals(uri.getAuthority());
+ }
+
+ /**
+ * @param uri The Uri to check.
+ * @return Whether the Uri authority is MediaProvider.
+ */
+ public static boolean isMediaDocument(Uri uri) {
+ return "com.android.providers.media.documents".equals(uri.getAuthority());
+ }
+
+}
diff --git a/zbarlibary/src/main/java/cn/bertsir/zbar/utils/PermissionConstants.java b/zbarlibary/src/main/java/cn/bertsir/zbar/utils/PermissionConstants.java
new file mode 100644
index 0000000..1063fba
--- /dev/null
+++ b/zbarlibary/src/main/java/cn/bertsir/zbar/utils/PermissionConstants.java
@@ -0,0 +1,91 @@
+package cn.bertsir.zbar.utils;
+
+import android.Manifest;
+import android.Manifest.permission;
+import android.annotation.SuppressLint;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+
+/**
+ *
+ * author: Blankj
+ * blog : http://blankj.com
+ * time : 2017/12/29
+ * desc : constants of permission
+ *
+ */
+@SuppressLint("InlinedApi")
+public final class PermissionConstants {
+
+ public static final String CALENDAR = Manifest.permission_group.CALENDAR;
+ public static final String CAMERA = Manifest.permission_group.CAMERA;
+ public static final String CONTACTS = Manifest.permission_group.CONTACTS;
+ public static final String LOCATION = Manifest.permission_group.LOCATION;
+ public static final String MICROPHONE = Manifest.permission_group.MICROPHONE;
+ public static final String PHONE = Manifest.permission_group.PHONE;
+ public static final String SENSORS = Manifest.permission_group.SENSORS;
+ public static final String SMS = Manifest.permission_group.SMS;
+ public static final String STORAGE = Manifest.permission_group.STORAGE;
+
+ private static final String[] GROUP_CALENDAR = {
+ permission.READ_CALENDAR, permission.WRITE_CALENDAR
+ };
+ private static final String[] GROUP_CAMERA = {
+ permission.CAMERA
+ };
+ private static final String[] GROUP_CONTACTS = {
+ permission.READ_CONTACTS, permission.WRITE_CONTACTS, permission.GET_ACCOUNTS
+ };
+ private static final String[] GROUP_LOCATION = {
+ permission.ACCESS_FINE_LOCATION, permission.ACCESS_COARSE_LOCATION
+ };
+ private static final String[] GROUP_MICROPHONE = {
+ permission.RECORD_AUDIO
+ };
+ private static final String[] GROUP_PHONE = {
+ permission.READ_PHONE_STATE, permission.CALL_PHONE
+ , permission.READ_CALL_LOG, permission.WRITE_CALL_LOG,
+ permission.ADD_VOICEMAIL, permission.USE_SIP, permission.PROCESS_OUTGOING_CALLS
+ };
+ private static final String[] GROUP_SENSORS = {
+ permission.BODY_SENSORS
+ };
+ private static final String[] GROUP_SMS = {
+ permission.SEND_SMS, permission.RECEIVE_SMS, permission.READ_SMS,
+ permission.RECEIVE_WAP_PUSH, permission.RECEIVE_MMS,
+ };
+ private static final String[] GROUP_STORAGE = {
+ permission.READ_EXTERNAL_STORAGE, permission.WRITE_EXTERNAL_STORAGE
+ };
+
+ //@StringDef({CALENDAR, CAMERA, CONTACTS, LOCATION, MICROPHONE, PHONE, SENSORS, SMS, STORAGE,})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Permission {
+ }
+
+ public static String[] getPermissions(@Permission final String permission) {
+ switch (permission) {
+ case CALENDAR:
+ return GROUP_CALENDAR;
+ case CAMERA:
+ return GROUP_CAMERA;
+ case CONTACTS:
+ return GROUP_CONTACTS;
+ case LOCATION:
+ return GROUP_LOCATION;
+ case MICROPHONE:
+ return GROUP_MICROPHONE;
+ case PHONE:
+ return GROUP_PHONE;
+ case SENSORS:
+ return GROUP_SENSORS;
+ case SMS:
+ return GROUP_SMS;
+ case STORAGE:
+ return GROUP_STORAGE;
+ }
+ return new String[]{permission};
+ }
+}
diff --git a/zbarlibary/src/main/java/cn/bertsir/zbar/utils/PermissionUtils.java b/zbarlibary/src/main/java/cn/bertsir/zbar/utils/PermissionUtils.java
new file mode 100644
index 0000000..ff5f1ed
--- /dev/null
+++ b/zbarlibary/src/main/java/cn/bertsir/zbar/utils/PermissionUtils.java
@@ -0,0 +1,369 @@
+package cn.bertsir.zbar.utils;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.graphics.Color;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Bundle;
+
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.WindowManager;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
+import androidx.core.content.ContextCompat;
+
+
+/**
+ *
+ * author: Blankj
+ * blog : http://blankj.com
+ * time : 2017/12/29
+ * desc : utils about permission
+ *
+ */
+public final class PermissionUtils {
+
+ private static List PERMISSIONS = null;
+
+ private static PermissionUtils sInstance;
+
+ private OnRationaleListener mOnRationaleListener;
+ private SimpleCallback mSimpleCallback;
+ private FullCallback mFullCallback;
+ private ThemeCallback mThemeCallback;
+ private Set mPermissions;
+ private List mPermissionsRequest;
+ private List mPermissionsGranted;
+ private List mPermissionsDenied;
+ private List mPermissionsDeniedForever;
+ private static Context mApp;
+
+ /**
+ * Return the permissions used in application.
+ *
+ * @return the permissions used in application
+ */
+ public static List getPermissions() {
+ return getPermissions(mApp.getPackageName());
+ }
+
+
+ /**
+ * Return the permissions used in application.
+ *
+ * @param packageName The name of the package.
+ * @return the permissions used in application
+ */
+ public static List getPermissions(final String packageName) {
+ PackageManager pm = mApp.getPackageManager();
+ try {
+ return Arrays.asList(
+ pm.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS)
+ .requestedPermissions
+ );
+ } catch (PackageManager.NameNotFoundException e) {
+ e.printStackTrace();
+ return Collections.emptyList();
+ }
+ }
+
+ /**
+ * Return whether you have granted the permissions.
+ *
+ * @param permissions The permissions.
+ * @return {@code true}: yes
{@code false}: no
+ */
+ public static boolean isGranted(final String... permissions) {
+ for (String permission : permissions) {
+ if (!isGranted(permission)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private static boolean isGranted(final String permission) {
+ return Build.VERSION.SDK_INT < Build.VERSION_CODES.M
+ || PackageManager.PERMISSION_GRANTED
+ == ContextCompat.checkSelfPermission(mApp, permission);
+ }
+
+ /**
+ * Launch the application's details settings.
+ */
+ public static void launchAppDetailsSettings() {
+ Intent intent = new Intent("android.settings.APPLICATION_DETAILS_SETTINGS");
+ intent.setData(Uri.parse("package:" + mApp.getPackageName()));
+ mApp.startActivity(intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
+ }
+
+ /**
+ * Set the permissions.
+ *
+ * @param permissions The permissions.
+ * @return the single {@link PermissionUtils} instance
+ */
+ public static PermissionUtils permission(Context mContext, @PermissionConstants.Permission final String...
+ permissions
+ ) {
+ mApp = mContext;
+ PERMISSIONS = getPermissions();
+ return new PermissionUtils(permissions);
+ }
+
+ private PermissionUtils(final String... permissions) {
+ mPermissions = new LinkedHashSet<>();
+ for (String permission : permissions) {
+ for (String aPermission : PermissionConstants.getPermissions(permission)) {
+ if (PERMISSIONS.contains(aPermission)) {
+ mPermissions.add(aPermission);
+ }
+ }
+ }
+ sInstance = this;
+ }
+
+ /**
+ * Set rationale listener.
+ *
+ * @param listener The rationale listener.
+ * @return the single {@link PermissionUtils} instance
+ */
+ public PermissionUtils rationale(final OnRationaleListener listener) {
+ mOnRationaleListener = listener;
+ return this;
+ }
+
+ /**
+ * Set the simple call back.
+ *
+ * @param callback the simple call back
+ * @return the single {@link PermissionUtils} instance
+ */
+ public PermissionUtils callback(final SimpleCallback callback) {
+ mSimpleCallback = callback;
+ return this;
+ }
+
+ /**
+ * Set the full call back.
+ *
+ * @param callback the full call back
+ * @return the single {@link PermissionUtils} instance
+ */
+ public PermissionUtils callback(final FullCallback callback) {
+ mFullCallback = callback;
+ return this;
+ }
+
+ /**
+ * Set the theme callback.
+ *
+ * @param callback The theme callback.
+ * @return the single {@link PermissionUtils} instance
+ */
+ public PermissionUtils theme(final ThemeCallback callback) {
+ mThemeCallback = callback;
+ return this;
+ }
+
+ /**
+ * Start request.
+ */
+ public void request() {
+ mPermissionsGranted = new ArrayList<>();
+ mPermissionsRequest = new ArrayList<>();
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
+ mPermissionsGranted.addAll(mPermissions);
+ requestCallback();
+ } else {
+ for (String permission : mPermissions) {
+ if (isGranted(permission)) {
+ mPermissionsGranted.add(permission);
+ } else {
+ mPermissionsRequest.add(permission);
+ }
+ }
+ if (mPermissionsRequest.isEmpty()) {
+ requestCallback();
+ } else {
+ startPermissionActivity();
+ }
+ }
+ }
+
+ @RequiresApi(api = Build.VERSION_CODES.M)
+ private void startPermissionActivity() {
+ mPermissionsDenied = new ArrayList<>();
+ mPermissionsDeniedForever = new ArrayList<>();
+ PermissionActivity.start(mApp);
+ }
+
+ @RequiresApi(api = Build.VERSION_CODES.M)
+ private boolean rationale(final Activity activity) {
+ boolean isRationale = false;
+ if (mOnRationaleListener != null) {
+ for (String permission : mPermissionsRequest) {
+ if (activity.shouldShowRequestPermissionRationale(permission)) {
+ getPermissionsStatus(activity);
+ mOnRationaleListener.rationale(new OnRationaleListener.ShouldRequest() {
+ @Override
+ public void again(boolean again) {
+ if (again) {
+ startPermissionActivity();
+ } else {
+ requestCallback();
+ }
+ }
+ });
+ isRationale = true;
+ break;
+ }
+ }
+ mOnRationaleListener = null;
+ }
+ return isRationale;
+ }
+
+ private void getPermissionsStatus(final Activity activity) {
+ for (String permission : mPermissionsRequest) {
+ if (isGranted(permission)) {
+ mPermissionsGranted.add(permission);
+ } else {
+ mPermissionsDenied.add(permission);
+ if (!activity.shouldShowRequestPermissionRationale(permission)) {
+ mPermissionsDeniedForever.add(permission);
+ }
+ }
+ }
+ }
+
+ private void requestCallback() {
+ if (mSimpleCallback != null) {
+ if (mPermissionsRequest.size() == 0
+ || mPermissions.size() == mPermissionsGranted.size()) {
+ mSimpleCallback.onGranted();
+ } else {
+ if (!mPermissionsDenied.isEmpty()) {
+ mSimpleCallback.onDenied();
+ }
+ }
+ mSimpleCallback = null;
+ }
+ if (mFullCallback != null) {
+ if (mPermissionsRequest.size() == 0
+ || mPermissions.size() == mPermissionsGranted.size()) {
+ mFullCallback.onGranted(mPermissionsGranted);
+ } else {
+ if (!mPermissionsDenied.isEmpty()) {
+ mFullCallback.onDenied(mPermissionsDeniedForever, mPermissionsDenied);
+ }
+ }
+ mFullCallback = null;
+ }
+ mOnRationaleListener = null;
+ mThemeCallback = null;
+ }
+
+ private void onRequestPermissionsResult(final Activity activity) {
+ getPermissionsStatus(activity);
+ requestCallback();
+ }
+
+
+ @RequiresApi(api = Build.VERSION_CODES.M)
+ public static class PermissionActivity extends Activity {
+
+ public static void start(final Context context) {
+ Intent starter = new Intent(context, PermissionActivity.class);
+ starter.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ context.startActivity(starter);
+ }
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
+ | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);
+ getWindow().setStatusBarColor(Color.TRANSPARENT);
+ if (sInstance == null) {
+ super.onCreate(savedInstanceState);
+ Log.e("PermissionUtils", "request permissions failed");
+ finish();
+ return;
+ }
+ if (sInstance.mThemeCallback != null) {
+ sInstance.mThemeCallback.onActivityCreate(this);
+ }
+ super.onCreate(savedInstanceState);
+
+ if (sInstance.rationale(this)) {
+ finish();
+ return;
+ }
+ if (sInstance.mPermissionsRequest != null) {
+ int size = sInstance.mPermissionsRequest.size();
+ if (size <= 0) {
+ finish();
+ return;
+ }
+ requestPermissions(sInstance.mPermissionsRequest.toArray(new String[size]), 1);
+ }
+ }
+
+ @Override
+ public void onRequestPermissionsResult(int requestCode,
+ @NonNull String[] permissions,
+ @NonNull int[] grantResults) {
+ sInstance.onRequestPermissionsResult(this);
+ finish();
+ }
+
+ @Override
+ public boolean dispatchTouchEvent(MotionEvent ev) {
+ finish();
+ return true;
+ }
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // interface
+ ///////////////////////////////////////////////////////////////////////////
+
+ public interface OnRationaleListener {
+
+ void rationale(ShouldRequest shouldRequest);
+
+ interface ShouldRequest {
+ void again(boolean again);
+ }
+ }
+
+ public interface SimpleCallback {
+ void onGranted();
+
+ void onDenied();
+ }
+
+ public interface FullCallback {
+ void onGranted(List permissionsGranted);
+
+ void onDenied(List permissionsDeniedForever, List permissionsDenied);
+ }
+
+ public interface ThemeCallback {
+ void onActivityCreate(Activity activity);
+ }
+}
\ No newline at end of file
diff --git a/zbarlibary/src/main/java/cn/bertsir/zbar/utils/QRUtils.java b/zbarlibary/src/main/java/cn/bertsir/zbar/utils/QRUtils.java
new file mode 100644
index 0000000..e800d28
--- /dev/null
+++ b/zbarlibary/src/main/java/cn/bertsir/zbar/utils/QRUtils.java
@@ -0,0 +1,670 @@
+package cn.bertsir.zbar.utils;
+
+import android.content.Context;
+import android.content.res.Configuration;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.ColorMatrix;
+import android.graphics.ColorMatrixColorFilter;
+import android.graphics.Matrix;
+import android.graphics.Paint;
+import android.graphics.Point;
+import android.graphics.PointF;
+import android.graphics.drawable.BitmapDrawable;
+import android.os.Build;
+import android.os.Vibrator;
+import android.text.TextUtils;
+import android.view.Gravity;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.WindowManager;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.BinaryBitmap;
+import com.google.zxing.ChecksumException;
+import com.google.zxing.DecodeHintType;
+import com.google.zxing.EncodeHintType;
+import com.google.zxing.FormatException;
+import com.google.zxing.MultiFormatWriter;
+import com.google.zxing.NotFoundException;
+import com.google.zxing.RGBLuminanceSource;
+import com.google.zxing.Result;
+import com.google.zxing.WriterException;
+import com.google.zxing.common.BitMatrix;
+import com.google.zxing.common.GlobalHistogramBinarizer;
+import com.google.zxing.qrcode.QRCodeReader;
+import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
+
+import java.io.File;
+import java.util.Hashtable;
+
+import cn.bertsir.zbar.Qr.Config;
+import cn.bertsir.zbar.Qr.Image;
+import cn.bertsir.zbar.Qr.ImageScanner;
+import cn.bertsir.zbar.Qr.Symbol;
+import cn.bertsir.zbar.Qr.SymbolSet;
+
+/**
+ * Created by Bert on 2017/9/20.
+ */
+
+public class QRUtils {
+
+ private static QRUtils instance;
+ private Bitmap scanBitmap;
+ private Context mContext;
+
+
+ public static QRUtils getInstance() {
+ if (instance == null) {
+ instance = new QRUtils();
+ }
+ return instance;
+ }
+
+
+
+ /**
+ * 识别本地二维码
+ *
+ * @param path
+ * @return
+ */
+ public String decodeQRcode(String path) throws Exception {
+ //对图片进行灰度处理,为了兼容彩色二维码
+ Bitmap qrbmp = compressImage(path);
+ qrbmp = toGrayscale(qrbmp);
+ if (qrbmp != null) {
+ return decodeQRcode(qrbmp);
+ } else {
+ return "";
+ }
+
+ }
+
+ public String decodeQRcode(ImageView iv) throws Exception {
+ Bitmap qrbmp = ((BitmapDrawable) (iv).getDrawable()).getBitmap();
+ if (qrbmp != null) {
+ return decodeQRcode(qrbmp);
+ } else {
+ return "";
+ }
+ }
+
+ public String decodeQRcode(Bitmap barcodeBmp) throws Exception {
+ int width = barcodeBmp.getWidth();
+ int height = barcodeBmp.getHeight();
+ int[] pixels = new int[width * height];
+ barcodeBmp.getPixels(pixels, 0, width, 0, 0, width, height);
+ Image barcode = new Image(width, height, "RGB4");
+ barcode.setData(pixels);
+ ImageScanner reader = new ImageScanner();
+ reader.setConfig(Symbol.NONE, Config.ENABLE, 0);
+ reader.setConfig(Symbol.QRCODE, Config.ENABLE, 1);
+ int result = reader.scanImage(barcode.convert("Y800"));
+ String qrCodeString = null;
+ if (result != 0) {
+ SymbolSet syms = reader.getResults();
+ for (Symbol sym : syms) {
+ qrCodeString = sym.getData();
+ }
+ }
+ barcodeBmp.recycle();
+ return qrCodeString;
+ }
+
+
+
+ /**
+ * 扫描二维码图片的方法
+ * @param path
+ * @return
+ */
+ public String decodeQRcodeByZxing(String path) {
+ if (TextUtils.isEmpty(path)) {
+ return null;
+
+ }
+ Hashtable hints = new Hashtable();
+ hints.put(DecodeHintType.CHARACTER_SET, "UTF-8"); // 设置二维码内容的编码
+ Bitmap scanBitmap = compressImage(path);
+ int[] data = new int[scanBitmap.getWidth() * scanBitmap.getHeight()];
+ scanBitmap.getPixels(data, 0, scanBitmap.getWidth(), 0, 0, scanBitmap.getWidth(), scanBitmap.getHeight());
+ RGBLuminanceSource rgbLuminanceSource = new RGBLuminanceSource(scanBitmap.getWidth(),scanBitmap.getHeight(),data);
+ BinaryBitmap binaryBitmap = new BinaryBitmap(new GlobalHistogramBinarizer(rgbLuminanceSource));
+ QRCodeReader reader = new QRCodeReader();
+ Result result = null;
+ try {
+ result = reader.decode(binaryBitmap, hints);
+ } catch (NotFoundException e) {
+
+ }catch (ChecksumException e){
+
+ }catch(FormatException e){
+
+ }
+ if(result == null){
+ return "";
+ }else {
+ return result.getText();
+ }
+ }
+
+ /**
+ * 扫描二维码图片的方法
+ * @return
+ */
+ public String decodeQRcodeByZxing(Bitmap bitmap) {
+ Hashtable hints = new Hashtable();
+ hints.put(DecodeHintType.CHARACTER_SET, "UTF-8"); // 设置二维码内容的编码
+ scanBitmap =bitmap;
+ int[] data = new int[scanBitmap.getWidth() * scanBitmap.getHeight()];
+ scanBitmap.getPixels(data, 0, scanBitmap.getWidth(), 0, 0, scanBitmap.getWidth(), scanBitmap.getHeight());
+ RGBLuminanceSource rgbLuminanceSource = new RGBLuminanceSource(scanBitmap.getWidth(),scanBitmap.getHeight(),data);
+ BinaryBitmap binaryBitmap = new BinaryBitmap(new GlobalHistogramBinarizer(rgbLuminanceSource));
+ QRCodeReader reader = new QRCodeReader();
+ Result result = null;
+ try {
+ result = reader.decode(binaryBitmap, hints);
+ } catch (NotFoundException e) {
+
+ }catch (ChecksumException e){
+
+ }catch(FormatException e){
+
+ }
+ if(result == null){
+ return "";
+ }else {
+ return result.getText();
+ }
+
+ }
+
+
+ /**
+ * 识别本地条形码
+ *
+ * @param url
+ * @return
+ */
+ public String decodeBarcode(String url) {
+ Bitmap qrbmp = BitmapFactory.decodeFile(url);
+ if (qrbmp != null) {
+ return decodeBarcode(qrbmp);
+ } else {
+ return "";
+ }
+
+ }
+
+ public String decodeBarcode(ImageView iv) {
+ Bitmap qrbmp = ((BitmapDrawable) (iv).getDrawable()).getBitmap();
+ if (qrbmp != null) {
+ return decodeBarcode(qrbmp);
+ } else {
+ return "";
+ }
+ }
+
+ public String decodeBarcode(Bitmap barcodeBmp) {
+ int width = barcodeBmp.getWidth();
+ int height = barcodeBmp.getHeight();
+ int[] pixels = new int[width * height];
+ barcodeBmp.getPixels(pixels, 0, width, 0, 0, width, height);
+ Image barcode = new Image(width, height, "RGB4");
+ barcode.setData(pixels);
+ ImageScanner reader = new ImageScanner();
+ reader.setConfig(Symbol.NONE, Config.ENABLE, 0);
+ reader.setConfig(Symbol.CODE128, Config.ENABLE, 1);
+ reader.setConfig(Symbol.CODE39, Config.ENABLE, 1);
+ reader.setConfig(Symbol.EAN13, Config.ENABLE, 1);
+ reader.setConfig(Symbol.EAN8, Config.ENABLE, 1);
+ reader.setConfig(Symbol.UPCA, Config.ENABLE, 1);
+ reader.setConfig(Symbol.UPCE, Config.ENABLE, 1);
+ int result = reader.scanImage(barcode.convert("Y800"));
+ String qrCodeString = null;
+ if (result != 0) {
+ SymbolSet syms = reader.getResults();
+ for (Symbol sym : syms) {
+ qrCodeString = sym.getData();
+ }
+ }
+ return qrCodeString;
+ }
+
+
+ /**
+ * 生成二维码
+ *
+ * @param content
+ * @return
+ */
+ public Bitmap createQRCode(String content) {
+ return createQRCode(content, 300, 300);
+ }
+
+ /**
+ * 生成二维码
+ *
+ * @param content
+ * @return
+ */
+ public Bitmap createQRCode(String content, int width, int height) {
+ Bitmap bitmap = null;
+ BitMatrix result = null;
+ MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
+ try {
+ Hashtable hints = new Hashtable();
+ hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);//这里调整二维码的容错率
+ hints.put(EncodeHintType.MARGIN, 1); //设置白边取值1-4,值越大白边越大
+ result = multiFormatWriter.encode(new String(content.getBytes("UTF-8"), "ISO-8859-1"), BarcodeFormat
+ .QR_CODE, width, height, hints);
+ int w = result.getWidth();
+ int h = result.getHeight();
+ int[] pixels = new int[w * h];
+ for (int y = 0; y < h; y++) {
+ int offset = y * w;
+ for (int x = 0; x < w; x++) {
+ pixels[offset + x] = result.get(x, y) ? Color.BLACK : Color.WHITE;
+ }
+ }
+ bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
+ bitmap.setPixels(pixels, 0, w, 0, 0, w, h);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return bitmap;
+ }
+
+
+ /**
+ * 生成带logo的二维码
+ *
+ * @param content
+ * @param logo
+ * @return
+ */
+ public Bitmap createQRCodeAddLogo(String content, Bitmap logo) {
+ Bitmap qrCode = createQRCode(content);
+ int qrheight = qrCode.getHeight();
+ int qrwidth = qrCode.getWidth();
+ int waterWidth = (int) (qrwidth * 0.3);//0.3为logo占二维码大小的倍数 建议不要过大,否则二维码失效
+ float scale = waterWidth / (float) logo.getWidth();
+ Bitmap waterQrcode = createWaterMaskCenter(qrCode, zoomImg(logo, scale));
+ return waterQrcode;
+ }
+
+
+ public Bitmap createQRCodeAddLogo(String content, int width, int height, Bitmap logo) {
+ Bitmap qrCode = createQRCode(content, width, height);
+ int qrheight = qrCode.getHeight();
+ int qrwidth = qrCode.getWidth();
+ int waterWidth = (int) (qrwidth * 0.3);//0.3为logo占二维码大小的倍数 建议不要过大,否则二维码失效
+ float scale = waterWidth / (float) logo.getWidth();
+ Bitmap waterQrcode = createWaterMaskCenter(qrCode, zoomImg(logo, scale));
+ return waterQrcode;
+ }
+
+ /**
+ * 生成条形码
+ *
+ * @param context
+ * @param contents
+ * @param desiredWidth
+ * @param desiredHeight
+ * @return
+ */
+ @Deprecated
+ public Bitmap createBarcode(Context context, String contents, int desiredWidth, int desiredHeight) {
+ if (TextUtils.isEmpty(contents)) {
+ throw new NullPointerException("contents not be null");
+ }
+ if (desiredWidth == 0 || desiredHeight == 0) {
+ throw new NullPointerException("desiredWidth or desiredHeight not be null");
+ }
+ Bitmap resultBitmap;
+ /**
+ * 条形码的编码类型
+ */
+ BarcodeFormat barcodeFormat = BarcodeFormat.CODE_128;
+
+ resultBitmap = encodeAsBitmap(contents, barcodeFormat,
+ desiredWidth, desiredHeight);
+ return resultBitmap;
+ }
+
+ /**
+ * 生成条形码
+ *
+ * @param context
+ * @param contents
+ * @param desiredWidth
+ * @param desiredHeight
+ * @return
+ */
+ public Bitmap createBarCodeWithText(Context context, String contents, int desiredWidth,
+ int desiredHeight) {
+ return createBarCodeWithText(context, contents, desiredWidth, desiredHeight, null);
+ }
+
+ public Bitmap createBarCodeWithText(Context context, String contents, int desiredWidth,
+ int desiredHeight, TextViewConfig config) {
+ if (TextUtils.isEmpty(contents)) {
+ throw new NullPointerException("contents not be null");
+ }
+ if (desiredWidth == 0 || desiredHeight == 0) {
+ throw new NullPointerException("desiredWidth or desiredHeight not be null");
+ }
+ Bitmap resultBitmap;
+
+ /**
+ * 条形码的编码类型
+ */
+ BarcodeFormat barcodeFormat = BarcodeFormat.CODE_128;
+
+ Bitmap barcodeBitmap = encodeAsBitmap(contents, barcodeFormat,
+ desiredWidth, desiredHeight);
+
+ Bitmap codeBitmap = createCodeBitmap(contents, barcodeBitmap.getWidth(),
+ barcodeBitmap.getHeight(), context, config);
+
+ resultBitmap = mixtureBitmap(barcodeBitmap, codeBitmap, new PointF(
+ 0, desiredHeight));
+ return resultBitmap;
+ }
+
+ private Bitmap encodeAsBitmap(String contents, BarcodeFormat format, int desiredWidth, int desiredHeight) {
+ final int WHITE = 0xFFFFFFFF;
+ final int BLACK = 0xFF000000;
+
+ MultiFormatWriter writer = new MultiFormatWriter();
+ BitMatrix result = null;
+ try {
+ result = writer.encode(contents, format, desiredWidth,
+ desiredHeight, null);
+ } catch (WriterException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ int width = result.getWidth();
+ int height = result.getHeight();
+ int[] pixels = new int[width * height];
+ // All are 0, or black, by default
+ for (int y = 0; y < height; y++) {
+ int offset = y * width;
+ for (int x = 0; x < width; x++) {
+ pixels[offset + x] = result.get(x, y) ? BLACK : WHITE;
+ }
+ }
+
+ Bitmap bitmap = Bitmap.createBitmap(width, height,
+ Bitmap.Config.ARGB_8888);
+ bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
+ return bitmap;
+
+ }
+
+
+ private Bitmap createCodeBitmap(String contents, int width, int height, Context context,
+ TextViewConfig config) {
+ if (config == null) {
+ config = new TextViewConfig();
+ }
+ TextView tv = new TextView(context);
+ LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
+ LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
+ tv.setLayoutParams(layoutParams);
+ tv.setText(contents);
+ tv.setTextSize(config.size == 0 ? tv.getTextSize() : config.size);
+ tv.setHeight(height);
+ tv.setGravity(config.gravity);
+ tv.setMaxLines(config.maxLines);
+ tv.setWidth(width);
+ tv.setDrawingCacheEnabled(true);
+ tv.setTextColor(config.color);
+ tv.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
+ View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
+ tv.layout(0, 0, tv.getMeasuredWidth(), tv.getMeasuredHeight());
+
+ tv.buildDrawingCache();
+ return tv.getDrawingCache();
+ }
+
+ public static class TextViewConfig {
+
+ private int gravity = Gravity.CENTER;
+ private int maxLines = 1;
+ private int color = Color.BLACK;
+ private float size;
+
+ public TextViewConfig() {
+ }
+
+ public void setGravity(int gravity) {
+ this.gravity = gravity;
+ }
+
+ public void setMaxLines(int maxLines) {
+ this.maxLines = maxLines;
+ }
+
+ public void setColor(int color) {
+ this.color = color;
+ }
+
+ public void setSize(float size) {
+ this.size = size;
+ }
+ }
+
+ /**
+ * 将两个Bitmap合并成一个
+ *
+ * @param first
+ * @param second
+ * @param fromPoint 第二个Bitmap开始绘制的起始位置(相对于第一个Bitmap)
+ * @return
+ */
+ private Bitmap mixtureBitmap(Bitmap first, Bitmap second, PointF fromPoint) {
+ if (first == null || second == null || fromPoint == null) {
+ return null;
+ }
+
+ int width = Math.max(first.getWidth(), second.getWidth());
+ Bitmap newBitmap = Bitmap.createBitmap(
+ width,
+ first.getHeight() + second.getHeight(), Bitmap.Config.ARGB_4444);
+ Canvas cv = new Canvas(newBitmap);
+ cv.drawBitmap(first, 0, 0, null);
+ cv.drawBitmap(second, fromPoint.x, fromPoint.y, null);
+ cv.save(Canvas.ALL_SAVE_FLAG);
+ cv.restore();
+
+ return newBitmap;
+ }
+
+ /**
+ * 设置水印图片到中间
+ *
+ * @param src
+ * @param watermark
+ * @return
+ */
+ private Bitmap createWaterMaskCenter(Bitmap src, Bitmap watermark) {
+ return createWaterMaskBitmap(src, watermark,
+ (src.getWidth() - watermark.getWidth()) / 2,
+ (src.getHeight() - watermark.getHeight()) / 2);
+ }
+
+ private Bitmap createWaterMaskBitmap(Bitmap src, Bitmap watermark, int paddingLeft, int paddingTop) {
+ if (src == null) {
+ return null;
+ }
+ int width = src.getWidth();
+ int height = src.getHeight();
+ Bitmap newb = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);// 创建一个新的和SRC长度宽度一样的位图
+ Canvas canvas = new Canvas(newb);
+ canvas.drawBitmap(src, 0, 0, null);
+ canvas.drawBitmap(watermark, paddingLeft, paddingTop, null);
+ canvas.save(Canvas.ALL_SAVE_FLAG);
+ canvas.restore();
+ return newb;
+ }
+
+ /**
+ * 缩放Bitmap
+ *
+ * @param bm
+ * @param f
+ * @return
+ */
+ private Bitmap zoomImg(Bitmap bm, float f) {
+
+ int width = bm.getWidth();
+ int height = bm.getHeight();
+
+ float scaleWidth = f;
+ float scaleHeight = f;
+
+ Matrix matrix = new Matrix();
+ matrix.postScale(scaleWidth, scaleHeight);
+
+ Bitmap newbm = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, true);
+ return newbm;
+ }
+
+
+ public boolean isMIUI() {
+ String manufacturer = Build.MANUFACTURER;
+ if ("xiaomi".equalsIgnoreCase(manufacturer)) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Return the width of screen, in pixel.
+ *
+ * @return the width of screen, in pixel
+ */
+ public int getScreenWidth(Context mContext) {
+ WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
+ Point point = new Point();
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
+ //noinspection ConstantConditions
+ wm.getDefaultDisplay().getRealSize(point);
+ } else {
+ //noinspection ConstantConditions
+ wm.getDefaultDisplay().getSize(point);
+ }
+ return point.x;
+ }
+
+ /**
+ * Return the height of screen, in pixel.
+ *
+ * @return the height of screen, in pixel
+ */
+ public int getScreenHeight(Context mContext) {
+ WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
+ Point point = new Point();
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
+ //noinspection ConstantConditions
+ wm.getDefaultDisplay().getRealSize(point);
+ } else {
+ //noinspection ConstantConditions
+ wm.getDefaultDisplay().getSize(point);
+ }
+ return point.y;
+ }
+
+ /**
+ * 返回当前屏幕是否为竖屏。
+ * @param context
+ * @return 当且仅当当前屏幕为竖屏时返回true,否则返回false。
+ */
+ public boolean isScreenOriatationPortrait(Context context) {
+ return context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT;
+ }
+
+ public float getFingerSpacing(MotionEvent event) {
+ float x = event.getX(0) - event.getX(1);
+ float y = event.getY(0) - event.getY(1);
+ return (float) Math.sqrt(x * x + y * y);
+ }
+
+
+
+ /**
+ * 对bitmap进行灰度处理
+ * @param bmpOriginal
+ * @return
+ */
+ private Bitmap toGrayscale(Bitmap bmpOriginal) {
+ int width, height;
+ height = bmpOriginal.getHeight();
+ width = bmpOriginal.getWidth();
+ Bitmap bmpGrayscale = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
+ Canvas c = new Canvas(bmpGrayscale);
+ Paint paint = new Paint();
+ ColorMatrix cm = new ColorMatrix();
+ cm.setSaturation(0);
+ ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
+ paint.setColorFilter(f);
+ c.drawBitmap(bmpOriginal, 0, 0, paint);
+ return bmpGrayscale;
+ }
+
+ /**
+ * 压缩图片
+ * @param path
+ * @return
+ */
+ private Bitmap compressImage(String path){
+ BitmapFactory.Options options = new BitmapFactory.Options();
+ options.inJustDecodeBounds = true; // 先获取原大小
+ scanBitmap = BitmapFactory.decodeFile(path,options);
+ options.inJustDecodeBounds = false;
+ int sampleSizeH = (int) (options.outHeight / (float) 800);
+ int sampleSizeW = (int) (options.outWidth / (float) 800);
+ int sampleSize = Math.max(sampleSizeH,sampleSizeW);
+ if (sampleSize <= 0) {
+ sampleSize = 1;
+ }
+ options.inSampleSize = sampleSize;
+ options.inPreferredConfig = Bitmap.Config.RGB_565;
+ Bitmap qrbmp = BitmapFactory.decodeFile(path,options);
+ return qrbmp;
+ }
+
+
+ public boolean deleteTempFile(String delFile) {
+ File file = new File(delFile);
+ if (file.exists() && file.isFile()) {
+ if (file.delete()) {
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+
+ //震动提醒
+ public void getVibrator(Context mContext){
+ Vibrator vibrator = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE);
+ long[] pattern = {0, 50, 0, 0};
+ vibrator.vibrate(pattern, -1);
+ }
+
+
+
+}
diff --git a/zbarlibary/src/main/java/cn/bertsir/zbar/utils/QrFileProvider.java b/zbarlibary/src/main/java/cn/bertsir/zbar/utils/QrFileProvider.java
new file mode 100644
index 0000000..57db4e3
--- /dev/null
+++ b/zbarlibary/src/main/java/cn/bertsir/zbar/utils/QrFileProvider.java
@@ -0,0 +1,11 @@
+package cn.bertsir.zbar.utils;
+
+
+import androidx.core.content.FileProvider;
+
+/**
+ * Created by Bert on 2019/3/4.
+ * Mail: bertsir@163.com
+ */
+public class QrFileProvider extends FileProvider {
+}
diff --git a/zbarlibary/src/main/java/cn/bertsir/zbar/view/CornerView.java b/zbarlibary/src/main/java/cn/bertsir/zbar/view/CornerView.java
new file mode 100644
index 0000000..a1df354
--- /dev/null
+++ b/zbarlibary/src/main/java/cn/bertsir/zbar/view/CornerView.java
@@ -0,0 +1,109 @@
+package cn.bertsir.zbar.view;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+
+import android.util.AttributeSet;
+import android.view.View;
+
+import androidx.annotation.Nullable;
+import cn.bertsir.zbar.R;
+
+/**
+ * Created by Bert on 2017/9/22.
+ */
+
+public class CornerView extends View {
+
+ private Paint paint;//声明画笔
+ private Canvas canvas;//画布
+
+ private static final String TAG = "CornerView";
+ private int width = 0;
+ private int height = 0;
+
+ private int cornerColor;
+ private int cornerWidth;
+ private int cornerGravity;
+
+
+ private static final int LEFT_TOP = 0;
+ private static final int LEFT_BOTTOM = 1;
+ private static final int RIGHT_TOP = 2;
+ private static final int RIGHT_BOTTOM = 3;
+
+ public CornerView(Context context) {
+ super(context,null);
+ }
+
+ public CornerView(Context context, @Nullable AttributeSet attrs) {
+ super(context, attrs);
+ TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CornerView);
+ cornerColor = a.getColor(R.styleable.CornerView_corner_color, getResources().getColor(R.color.common_color));
+ cornerWidth = (int) a.getDimension(R.styleable.CornerView_corner_width, 10);
+ cornerGravity = a.getInt(R.styleable.CornerView_corner_gravity, 1);
+ a.recycle();
+
+ paint=new Paint();//创建一个画笔
+ canvas=new Canvas();
+
+ paint.setStyle(Paint.Style.FILL);//设置非填充
+ paint.setStrokeWidth(cornerWidth);//笔宽5像素
+ paint.setColor(cornerColor);//设置为红笔
+ paint.setAntiAlias(true);//锯齿不显示
+ }
+
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ width = getMeasuredWidth();
+ height = getMeasuredHeight();
+ }
+
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+ switch (cornerGravity){
+ case LEFT_TOP:
+ canvas.drawLine(0, 0, width, 0, paint);
+ canvas.drawLine(0, 0, 0, height, paint);
+ break;
+ case LEFT_BOTTOM:
+ canvas.drawLine(0, 0, 0, height, paint);
+ canvas.drawLine(0, height, width, height, paint);
+ break;
+ case RIGHT_TOP:
+ canvas.drawLine(0, 0, width, 0, paint);
+ canvas.drawLine(width, 0, width, height, paint);
+ break;
+ case RIGHT_BOTTOM:
+ canvas.drawLine(width, 0, width, height, paint);
+ canvas.drawLine(0, height, width, height, paint);
+ break;
+ }
+
+ }
+
+
+ public void setColor(int color){
+ cornerColor = color;
+ paint.setColor(cornerColor);
+ invalidate();
+ }
+
+ public void setLineWidth(int dp){
+ cornerWidth = dip2px(dp);
+ paint.setStrokeWidth(cornerWidth);
+ invalidate();
+ }
+
+
+ public int dip2px(int dp) {
+ float density = getContext().getResources().getDisplayMetrics().density;
+ return (int) (dp * density + 0.5);
+ }
+}
diff --git a/zbarlibary/src/main/java/cn/bertsir/zbar/view/LineView.java b/zbarlibary/src/main/java/cn/bertsir/zbar/view/LineView.java
new file mode 100644
index 0000000..0a057b0
--- /dev/null
+++ b/zbarlibary/src/main/java/cn/bertsir/zbar/view/LineView.java
@@ -0,0 +1,61 @@
+package cn.bertsir.zbar.view;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.LinearGradient;
+import android.graphics.Paint;
+import android.graphics.Shader;
+import android.util.AttributeSet;
+import android.view.View;
+
+import cn.bertsir.zbar.R;
+
+import static android.R.attr.width;
+
+/**
+ * Created by Bert on 2017/9/22.
+ */
+
+@Deprecated
+public class LineView extends View {
+
+ private Paint paint;//声明画笔
+ private Canvas canvas;//画布
+ private int line_color = getResources().getColor(R.color.common_color);
+ private Shader mShader;
+
+ public LineView(Context context) {
+ super(context);
+ }
+
+ public LineView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+
+ paint=new Paint();//创建一个画笔
+ canvas=new Canvas();
+
+ paint.setStyle(Paint.Style.FILL);//设置非填充
+ paint.setStrokeWidth(10);//笔宽5像素
+ // paint.setColor(line_color);//设置为红笔
+ paint.setAntiAlias(true);//锯齿不显示
+ }
+
+ public void setLinecolor(int color){
+ line_color = color;
+ invalidate();
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+ String line_colors = String.valueOf(Integer.toHexString(line_color));
+ line_colors = line_colors.substring(line_colors.length() - 6, line_colors.length() - 0);
+ mShader = new LinearGradient(0,0,getMeasuredWidth(),0,new int[] {Color.parseColor("#00"+line_colors),line_color, Color.parseColor("#00"+line_colors),},null,
+ Shader.TileMode.CLAMP);
+ paint.setShader(mShader);
+ canvas.drawLine(0, 0, width, 0, paint);
+ }
+
+
+}
diff --git a/zbarlibary/src/main/java/cn/bertsir/zbar/view/ScanLineView.java b/zbarlibary/src/main/java/cn/bertsir/zbar/view/ScanLineView.java
new file mode 100644
index 0000000..7750b29
--- /dev/null
+++ b/zbarlibary/src/main/java/cn/bertsir/zbar/view/ScanLineView.java
@@ -0,0 +1,285 @@
+package cn.bertsir.zbar.view;
+
+import android.animation.ValueAnimator;
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.LinearGradient;
+import android.graphics.Matrix;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.Rect;
+import android.graphics.Shader;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.animation.Animation;
+import android.view.animation.DecelerateInterpolator;
+
+import cn.bertsir.zbar.R;
+
+/**
+ * Created by Bert on 2019-09-16.
+ * Mail: bertsir@163.com
+ */
+public class ScanLineView extends View {
+
+ private static final String TAG = "ScanView";
+
+ public static final int style_gridding = 0;//扫描区域的样式
+ public static final int style_radar = 1;
+ public static final int style_hybrid = 2;
+ public static final int style_line = 3;
+
+
+ private Rect mFrame;//最佳扫描区域的Rect
+
+ private Paint mScanPaint_Gridding;//网格样式画笔
+ private Paint mScanPaint_Radio;//雷达样式画笔
+ private Paint mScanPaint_Line;//线条样式画笔
+
+ private Path mBoundaryLinePath;//边框path
+ private Path mGriddingPath;//网格样式的path
+
+ private LinearGradient mLinearGradient_Radar;//雷达样式的画笔shader
+ private LinearGradient mLinearGradient_Gridding;//网格画笔的shader
+ private LinearGradient mLinearGradient_line;
+ private float mGriddingLineWidth = 4;//网格线的线宽,单位pix
+ private int mGriddingDensity = 50;//网格样式的,网格密度,值越大越密集
+
+
+ private float mCornerLineLen = 50f;//根据比例计算的边框长度,从四角定点向临近的定点画出的长度
+
+ private Matrix mScanMatrix;//变换矩阵,用来实现动画效果
+ private ValueAnimator mValueAnimator;//值动画,用来变换矩阵操作
+
+ private int mScanAnimatorDuration = 1800;//值动画的时长
+ private int mScancolor;//扫描颜色
+
+ private int mScanStyle = style_gridding;//网格 0:网格,1:纵向雷达 2:综合 3:线
+ private float animatedValue;
+
+
+ public ScanLineView(Context context) {
+ this(context, null);
+ }
+
+ // This constructor is used when the class is built from an XML resource.
+ public ScanLineView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+
+ }
+
+ public ScanLineView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ init();
+ }
+
+ private void init() {
+ // Initialize these once for performance rather than calling them every time in onDraw().
+ mScanPaint_Gridding = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mScanPaint_Gridding.setStyle(Paint.Style.STROKE);
+ mScanPaint_Gridding.setStrokeWidth(mGriddingLineWidth);
+
+ mScanPaint_Radio = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mScanPaint_Radio.setStyle(Paint.Style.FILL);
+ Resources resources = getResources();
+ mScancolor = resources.getColor(R.color.common_color);
+
+
+ mScanPaint_Line=new Paint();//创建一个画笔
+ mScanPaint_Line.setStyle(Paint.Style.FILL);//设置非填充
+ mScanPaint_Line.setStrokeWidth(10);//笔宽5像素
+ mScanPaint_Line.setAntiAlias(true);//锯齿不显示
+
+ //变换矩阵,用来处理扫描的上下扫描效果
+ mScanMatrix = new Matrix();
+ mScanMatrix.setTranslate(0, 30);
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ super.onLayout(changed, left, top, right, bottom);
+ mFrame = new Rect(left,top,right,bottom);
+
+ initBoundaryAndAnimator();
+ }
+
+ private void initBoundaryAndAnimator() {
+ if (mBoundaryLinePath == null) {
+ mBoundaryLinePath = new Path();
+ mBoundaryLinePath.moveTo(mFrame.left, mFrame.top + mCornerLineLen);
+ mBoundaryLinePath.lineTo(mFrame.left, mFrame.top);
+ mBoundaryLinePath.lineTo(mFrame.left + mCornerLineLen, mFrame.top);
+ mBoundaryLinePath.moveTo(mFrame.right - mCornerLineLen, mFrame.top);
+ mBoundaryLinePath.lineTo(mFrame.right, mFrame.top);
+ mBoundaryLinePath.lineTo(mFrame.right, mFrame.top + mCornerLineLen);
+ mBoundaryLinePath.moveTo(mFrame.right, mFrame.bottom - mCornerLineLen);
+ mBoundaryLinePath.lineTo(mFrame.right, mFrame.bottom);
+ mBoundaryLinePath.lineTo(mFrame.right - mCornerLineLen, mFrame.bottom);
+ mBoundaryLinePath.moveTo(mFrame.left + mCornerLineLen, mFrame.bottom);
+ mBoundaryLinePath.lineTo(mFrame.left, mFrame.bottom);
+ mBoundaryLinePath.lineTo(mFrame.left, mFrame.bottom - mCornerLineLen);
+ }
+
+ if (mValueAnimator == null) {
+ initScanValueAnim(mFrame.height());
+ }
+ }
+
+ @SuppressLint("DrawAllocation")
+ @Override
+ public void onDraw(Canvas canvas) {
+ if (mFrame == null||mBoundaryLinePath==null) {
+ return;
+ }
+ switch (mScanStyle) {
+ case style_gridding:
+ initGriddingPathAndStyle();
+ canvas.drawPath(mGriddingPath, mScanPaint_Gridding);
+ break;
+ case style_radar:
+ initRadarStyle();
+ canvas.drawRect(mFrame, mScanPaint_Radio);
+ break;
+ case style_line:
+ initLineStyle();
+ canvas.drawLine(0,(mFrame.height()- Math.abs(animatedValue)),getMeasuredWidth(),
+ (mFrame.height()- Math.abs(animatedValue)), mScanPaint_Line);
+ break;
+ case style_hybrid:
+ default:
+ initGriddingPathAndStyle();
+ initRadarStyle();
+ canvas.drawPath(mGriddingPath, mScanPaint_Gridding);
+ canvas.drawRect(mFrame, mScanPaint_Radio);
+ break;
+
+ }
+
+ }
+
+ private void initRadarStyle() {
+ if (mLinearGradient_Radar == null) {
+ mLinearGradient_Radar = new LinearGradient(0, mFrame.top, 0, mFrame.bottom + 0.01f * mFrame.height(),
+ new int[]{Color.TRANSPARENT, Color.TRANSPARENT, mScancolor, Color.TRANSPARENT}, new float[]{0, 0.85f, 0.99f, 1f}, LinearGradient.TileMode.CLAMP);
+ mLinearGradient_Radar.setLocalMatrix(mScanMatrix);
+ mScanPaint_Radio.setShader(mLinearGradient_Radar);
+ }
+ }
+
+ private void initLineStyle() {
+ if (mLinearGradient_line == null) {
+ String line_colors = String.valueOf(Integer.toHexString(mScancolor));
+ line_colors = line_colors.substring(line_colors.length() - 6, line_colors.length() - 0);
+ mLinearGradient_line = new LinearGradient(0,0,getMeasuredWidth(),0,new int[] {Color.parseColor("#00"+line_colors),
+ mScancolor, Color.parseColor("#00"+line_colors),},null, Shader.TileMode.CLAMP);
+ mLinearGradient_line.setLocalMatrix(mScanMatrix);
+ mScanPaint_Line.setShader(mLinearGradient_line);
+ }
+ }
+
+ private void initGriddingPathAndStyle() {
+ if (mGriddingPath == null) {
+ mGriddingPath = new Path();
+ float wUnit = mFrame.width() / (mGriddingDensity + 0f);
+ float hUnit = mFrame.height() / (mGriddingDensity + 0f);
+ for (int i = 0; i <= mGriddingDensity; i++) {
+ mGriddingPath.moveTo(mFrame.left + i * wUnit, mFrame.top);
+ mGriddingPath.lineTo(mFrame.left + i * wUnit, mFrame.bottom);
+ }
+ for (int i = 0; i <= mGriddingDensity; i++) {
+ mGriddingPath.moveTo(mFrame.left, mFrame.top + i * hUnit);
+ mGriddingPath.lineTo(mFrame.right, mFrame.top + i * hUnit);
+ }
+ }
+ if (mLinearGradient_Gridding == null) {
+ mLinearGradient_Gridding = new LinearGradient(0, mFrame.top, 0, mFrame.bottom + 0.01f * mFrame.height(), new int[]{Color.TRANSPARENT, Color.TRANSPARENT, mScancolor, Color.TRANSPARENT}, new float[]{0, 0.5f, 0.99f, 1f}, LinearGradient.TileMode.CLAMP);
+ mLinearGradient_Gridding.setLocalMatrix(mScanMatrix);
+ mScanPaint_Gridding.setShader(mLinearGradient_Gridding);
+
+ }
+ }
+
+ public void initScanValueAnim(int height) {
+ mValueAnimator = new ValueAnimator();
+ mValueAnimator.setDuration(mScanAnimatorDuration);
+ mValueAnimator.setFloatValues(-height, 0);
+ mValueAnimator.setRepeatMode(ValueAnimator.RESTART);
+ mValueAnimator.setInterpolator(new DecelerateInterpolator());
+ mValueAnimator.setRepeatCount(Animation.INFINITE);
+ mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+
+
+
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ if(mLinearGradient_Gridding == null){
+ initGriddingPathAndStyle();
+ }
+ if(mLinearGradient_Radar == null){
+ initRadarStyle();
+ }
+
+ if(mLinearGradient_line == null){
+ initLineStyle();
+ }
+
+ if (mScanMatrix != null ) {
+ animatedValue = (float) animation.getAnimatedValue();
+ mScanMatrix.setTranslate(0, animatedValue);
+ mLinearGradient_Gridding.setLocalMatrix(mScanMatrix);
+ mLinearGradient_Radar.setLocalMatrix(mScanMatrix);
+ mLinearGradient_line.setLocalMatrix(mScanMatrix);
+ //mScanPaint.setShader(mLinearGradient); //不是必须的设置到shader即可
+ invalidate();
+ }
+ }
+ });
+ mValueAnimator.start();
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ if (mValueAnimator != null && mValueAnimator.isRunning()) {
+ mValueAnimator.cancel();
+ }
+ super.onDetachedFromWindow();
+ }
+
+ //设定扫描的颜色
+ public void setScancolor(int colorValue) {
+ this.mScancolor = colorValue;
+ }
+
+ public void setScanAnimatorDuration(int duration) {
+ this.mScanAnimatorDuration = duration;
+ }
+
+
+ /*
+ * @description 扫描区域的样式
+ * @scanStyle
+ *
+ * */
+ public void setScanStyle(int scanStyle) {
+ this.mScanStyle = scanStyle;
+ }
+
+ /*
+ * 扫描区域网格的样式
+ * @params strokeWidth:网格的线宽
+ * @params density:网格的密度
+ * */
+ public void setScanGriddingStyle(float strokeWidh, int density) {
+ this.mGriddingLineWidth = strokeWidh;
+ this.mGriddingDensity = density;
+ }
+}
+
diff --git a/zbarlibary/src/main/java/cn/bertsir/zbar/view/ScanView.java b/zbarlibary/src/main/java/cn/bertsir/zbar/view/ScanView.java
new file mode 100644
index 0000000..9fede47
--- /dev/null
+++ b/zbarlibary/src/main/java/cn/bertsir/zbar/view/ScanView.java
@@ -0,0 +1,131 @@
+package cn.bertsir.zbar.view;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.FrameLayout;
+import android.widget.LinearLayout;
+
+import java.util.ArrayList;
+
+import cn.bertsir.zbar.Qr.Symbol;
+import cn.bertsir.zbar.QrConfig;
+import cn.bertsir.zbar.R;
+
+
+/**
+ * Created by Bert on 2017/9/20.
+ */
+
+public class ScanView extends FrameLayout {
+
+ private ScanLineView iv_scan_line;
+ private FrameLayout fl_scan;
+ private int CURRENT_TYEP = 1;
+ private CornerView cnv_left_top;
+ private CornerView cnv_left_bottom;
+ private CornerView cnv_right_top;
+ private CornerView cnv_right_bottom;
+ private ArrayList cornerViews;
+ private int line_speed = 3000;
+
+ public ScanView(Context context) {
+ super(context);
+ initView(context);
+ }
+
+ public ScanView(Context context,AttributeSet attrs) {
+ super(context, attrs);
+ initView(context);
+ }
+
+ public ScanView(Context context,AttributeSet attrs,int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ initView(context);
+ }
+
+ private void initView(Context mContext){
+ View scan_view = View.inflate(mContext, R.layout.view_scan, this);
+
+ cnv_left_top = (CornerView) scan_view.findViewById(R.id.cnv_left_top);
+ cnv_left_bottom = (CornerView) scan_view.findViewById(R.id.cnv_left_bottom);
+ cnv_right_top = (CornerView) scan_view.findViewById(R.id.cnv_right_top);
+ cnv_right_bottom = (CornerView) scan_view.findViewById(R.id.cnv_right_bottom);
+
+ cornerViews = new ArrayList<>();
+ cornerViews.add(cnv_left_top);
+ cornerViews.add(cnv_left_bottom);
+ cornerViews.add(cnv_right_top);
+ cornerViews.add(cnv_right_bottom);
+
+ iv_scan_line = (ScanLineView) scan_view.findViewById(R.id.iv_scan_line);
+
+ fl_scan = (FrameLayout) scan_view.findViewById(R.id.fl_scan);
+ getViewWidthHeight();
+
+ }
+
+ /**
+ * 设置扫描速度
+ * @param speed
+ */
+ public void setLineSpeed(int speed){
+ iv_scan_line.setScanAnimatorDuration(speed);
+ }
+
+
+ /**
+ * 设置扫描样式
+ */
+ public void setScanLineStyle(int style){
+ iv_scan_line.setScanStyle(style);
+ }
+
+
+ public void setType(int type){
+ CURRENT_TYEP = type;
+ LinearLayout.LayoutParams fl_params = (LinearLayout.LayoutParams) fl_scan.getLayoutParams();
+ if(CURRENT_TYEP == QrConfig.SCANVIEW_TYPE_QRCODE){
+ fl_params.width = dip2px(200);
+ fl_params.height = dip2px(200);
+ }else if(CURRENT_TYEP == QrConfig.SCANVIEW_TYPE_BARCODE){
+ fl_params.width = dip2px(300);
+ fl_params.height = dip2px(100);
+ }
+ fl_scan.setLayoutParams(fl_params);
+ }
+
+ public void setCornerColor(int color){
+ for (int i = 0; i < cornerViews.size(); i++) {
+ cornerViews.get(i).setColor(color);
+ }
+ }
+
+ public void setCornerWidth(int dp){
+ for (int i = 0; i < cornerViews.size(); i++) {
+ cornerViews.get(i).setLineWidth(dp);
+ }
+ }
+
+ public void setLineColor(int color){
+ iv_scan_line.setScancolor(color);
+ }
+
+ public int dip2px(int dp) {
+ float density = getContext().getResources().getDisplayMetrics().density;
+ return (int) (dp * density + 0.5);
+ }
+
+ public void getViewWidthHeight(){
+ fl_scan.post(new Runnable() {
+ @Override
+ public void run() {
+ Symbol.cropWidth = fl_scan.getWidth();
+ Symbol.cropHeight = fl_scan.getHeight();
+ }
+ });
+ }
+
+
+
+}
diff --git a/zbarlibary/src/main/java/cn/bertsir/zbar/view/VerticalSeekBar.java b/zbarlibary/src/main/java/cn/bertsir/zbar/view/VerticalSeekBar.java
new file mode 100644
index 0000000..d872981
--- /dev/null
+++ b/zbarlibary/src/main/java/cn/bertsir/zbar/view/VerticalSeekBar.java
@@ -0,0 +1,104 @@
+package cn.bertsir.zbar.view;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.widget.SeekBar;
+
+import cn.bertsir.zbar.R;
+
+/**
+ * Created by Bert on 2019/3/1.
+ * Mail: bertsir@163.com
+ */
+public class VerticalSeekBar extends SeekBar {
+ private static final String TAG = VerticalSeekBar.class.getSimpleName();
+
+ public static final int ROTATION_ANGLE_CW_90 = 90;
+ public static final int ROTATION_ANGLE_CW_270 = 270;
+
+ private int mRotationAngle = ROTATION_ANGLE_CW_90;
+
+ public VerticalSeekBar(Context context) {
+ super(context);//注意是super 而不是调用其他构造函数
+ initialize(context, null, 0, 0);
+ }
+
+ public VerticalSeekBar(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ initialize(context, attrs, 0, 0);
+ }
+
+ public VerticalSeekBar(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ initialize(context, attrs, defStyle, 0);
+ }
+
+ private void initialize(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+
+ if (attrs != null) {
+ TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.VerticalSeekBar, defStyleAttr, defStyleRes);
+ final int rotationAngle = a.getInteger(R.styleable.VerticalSeekBar_seekBarRotation, 0);
+ if (isValidRotationAngle(rotationAngle)) {
+ mRotationAngle = rotationAngle;
+ }
+ a.recycle();
+ }
+ }
+
+ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+ super.onSizeChanged(h, w, oldh, oldw);
+ }
+
+ @Override
+ protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(heightMeasureSpec, widthMeasureSpec);
+ setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth());
+ }
+
+ protected void onDraw(Canvas c) {
+ if (mRotationAngle == ROTATION_ANGLE_CW_270) {
+ //从下到上
+ c.rotate(270);
+ c.translate(-getHeight(), 0);
+ } else if (mRotationAngle == ROTATION_ANGLE_CW_90) {
+ //从上到下
+ c.rotate(90);
+ c.translate(0, -getWidth());
+ }
+
+ super.onDraw(c);
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ if (!isEnabled()) {
+ return false;
+ }
+
+ switch (event.getAction()) {
+ case MotionEvent.ACTION_DOWN:
+ case MotionEvent.ACTION_MOVE:
+ case MotionEvent.ACTION_UP:
+ if (mRotationAngle == ROTATION_ANGLE_CW_270) {
+ //从下到上
+ setProgress(getMax() - (int) (getMax() * event.getY() / getHeight()));
+ } else if (mRotationAngle == ROTATION_ANGLE_CW_90) {
+ //从上到下
+ setProgress((int) (getMax() * event.getY() / getHeight()));
+ }
+ onSizeChanged(getWidth(), getHeight(), 0, 0);
+ break;
+
+ case MotionEvent.ACTION_CANCEL:
+ break;
+ }
+ return true;
+ }
+
+ private static boolean isValidRotationAngle(int angle) {
+ return (angle == ROTATION_ANGLE_CW_90 || angle == ROTATION_ANGLE_CW_270);
+ }
+}
diff --git a/zbarlibary/src/main/res/color/dialog_pro_color.xml b/zbarlibary/src/main/res/color/dialog_pro_color.xml
new file mode 100644
index 0000000..7158810
--- /dev/null
+++ b/zbarlibary/src/main/res/color/dialog_pro_color.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/zbarlibary/src/main/res/drawable-xhdpi/capture.9.png b/zbarlibary/src/main/res/drawable-xhdpi/capture.9.png
new file mode 100644
index 0000000..4cefb98
Binary files /dev/null and b/zbarlibary/src/main/res/drawable-xhdpi/capture.9.png differ
diff --git a/zbarlibary/src/main/res/drawable-xhdpi/scanner_album.png b/zbarlibary/src/main/res/drawable-xhdpi/scanner_album.png
new file mode 100644
index 0000000..e17b79d
Binary files /dev/null and b/zbarlibary/src/main/res/drawable-xhdpi/scanner_album.png differ
diff --git a/zbarlibary/src/main/res/drawable-xhdpi/scanner_back_img.png b/zbarlibary/src/main/res/drawable-xhdpi/scanner_back_img.png
new file mode 100644
index 0000000..c36743f
Binary files /dev/null and b/zbarlibary/src/main/res/drawable-xhdpi/scanner_back_img.png differ
diff --git a/zbarlibary/src/main/res/drawable-xhdpi/scanner_light.png b/zbarlibary/src/main/res/drawable-xhdpi/scanner_light.png
new file mode 100644
index 0000000..43cc53c
Binary files /dev/null and b/zbarlibary/src/main/res/drawable-xhdpi/scanner_light.png differ
diff --git a/zbarlibary/src/main/res/drawable-xhdpi/shadow.png b/zbarlibary/src/main/res/drawable-xhdpi/shadow.png
new file mode 100644
index 0000000..6be3091
Binary files /dev/null and b/zbarlibary/src/main/res/drawable-xhdpi/shadow.png differ
diff --git a/zbarlibary/src/main/res/drawable/circle_trans_black.xml b/zbarlibary/src/main/res/drawable/circle_trans_black.xml
new file mode 100644
index 0000000..677cda7
--- /dev/null
+++ b/zbarlibary/src/main/res/drawable/circle_trans_black.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/zbarlibary/src/main/res/drawable/shape_dialog_bg.xml b/zbarlibary/src/main/res/drawable/shape_dialog_bg.xml
new file mode 100644
index 0000000..0339cfe
--- /dev/null
+++ b/zbarlibary/src/main/res/drawable/shape_dialog_bg.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/zbarlibary/src/main/res/layout/activity_qr.xml b/zbarlibary/src/main/res/layout/activity_qr.xml
new file mode 100644
index 0000000..3a2c76b
--- /dev/null
+++ b/zbarlibary/src/main/res/layout/activity_qr.xml
@@ -0,0 +1,126 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/zbarlibary/src/main/res/layout/dialog_loading.xml b/zbarlibary/src/main/res/layout/dialog_loading.xml
new file mode 100644
index 0000000..7eacdac
--- /dev/null
+++ b/zbarlibary/src/main/res/layout/dialog_loading.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/zbarlibary/src/main/res/layout/view_scan.xml b/zbarlibary/src/main/res/layout/view_scan.xml
new file mode 100644
index 0000000..bf487b5
--- /dev/null
+++ b/zbarlibary/src/main/res/layout/view_scan.xml
@@ -0,0 +1,114 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/zbarlibary/src/main/res/raw/qrcode.mp3 b/zbarlibary/src/main/res/raw/qrcode.mp3
new file mode 100644
index 0000000..620701e
Binary files /dev/null and b/zbarlibary/src/main/res/raw/qrcode.mp3 differ
diff --git a/zbarlibary/src/main/res/values/attrs.xml b/zbarlibary/src/main/res/values/attrs.xml
new file mode 100644
index 0000000..93e83ff
--- /dev/null
+++ b/zbarlibary/src/main/res/values/attrs.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/zbarlibary/src/main/res/values/colors.xml b/zbarlibary/src/main/res/values/colors.xml
new file mode 100644
index 0000000..e6c7bec
--- /dev/null
+++ b/zbarlibary/src/main/res/values/colors.xml
@@ -0,0 +1,4 @@
+
+
+ #ff5f00
+
\ No newline at end of file
diff --git a/zbarlibary/src/main/res/values/dimens.xml b/zbarlibary/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..eaabc1d
--- /dev/null
+++ b/zbarlibary/src/main/res/values/dimens.xml
@@ -0,0 +1,6 @@
+
+
+
+ 200dp
+
+
\ No newline at end of file
diff --git a/zbarlibary/src/main/res/values/strings.xml b/zbarlibary/src/main/res/values/strings.xml
new file mode 100644
index 0000000..a65db67
--- /dev/null
+++ b/zbarlibary/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ zBarLibary
+
diff --git a/zbarlibary/src/main/res/values/styles.xml b/zbarlibary/src/main/res/values/styles.xml
new file mode 100644
index 0000000..662a895
--- /dev/null
+++ b/zbarlibary/src/main/res/values/styles.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/zbarlibary/src/main/res/xml/qr_file_paths.xml b/zbarlibary/src/main/res/xml/qr_file_paths.xml
new file mode 100644
index 0000000..b3a772a
--- /dev/null
+++ b/zbarlibary/src/main/res/xml/qr_file_paths.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file