Экран сканера

This commit is contained in:
Ivan Murashov
2017-07-19 18:59:04 +03:00
parent ff8ddf4334
commit bb45d252f1
31 changed files with 223 additions and 127 deletions

View File

@@ -15,8 +15,8 @@ apply plugin: 'com.android.application'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android {
compileSdkVersion 21
buildToolsVersion '21.0.0'
compileSdkVersion 25
buildToolsVersion '25.0.0'
lintOptions {
disable 'InvalidPackage'
@@ -48,7 +48,5 @@ flutter {
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile "com.google.android.gms:play-services-gcm:11.0.1"
androidTestCompile 'com.android.support:support-annotations:21.0.0'
androidTestCompile 'com.android.support.test:runner:0.5'
androidTestCompile 'com.android.support.test:rules:0.5'
compile 'com.android.support:appcompat-v7:25.0.0'
}

View File

@@ -17,7 +17,7 @@
In most cases you can leave this as-is, but you if you want to provide
additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here. -->
<application android:name="io.flutter.app.FlutterApplication" android:label="checker" android:icon="@mipmap/ic_launcher">
<application android:name="io.flutter.app.FlutterApplication" android:label="@string/app_name" android:icon="@mipmap/ic_launcher_app">
<activity android:name="com.dinect.checker.activity.MainActivity"
android:launchMode="singleTop"
android:theme="@android:style/Theme.Black.NoTitleBar"
@@ -31,7 +31,7 @@
</activity>
<activity android:name="com.dinect.checker.activity.CameraActivity"
android:theme="@android:style/Theme.Black.NoTitleBar"/>
android:theme="@style/AppTheme"/>
<service
android:name="com.dinect.checker.service.RegistrationIntentService"

View File

@@ -1,46 +1,53 @@
package com.dinect.checker.activity;
import android.app.Activity;
import android.support.v7.app.AppCompatActivity;
import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
import android.util.DisplayMetrics;
import android.content.res.Resources ;
import android.view.View;
import android.view.Menu;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.FrameLayout;
import android.widget.Button;
import android.graphics.Rect;
import android.support.v7.widget.Toolbar;
import android.hardware.Camera;
import android.hardware.Camera.PreviewCallback;
import android.hardware.Camera.AutoFocusCallback;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.Size;
import android.support.v7.app.ActionBar;
import android.widget.TextView;
import android.widget.Toast;
import android.view.SurfaceView;
import android.view.SurfaceHolder;
import android.graphics.ImageFormat;
import java.io.ByteArrayOutputStream;
import java.util.HashMap;
import net.sourceforge.zbar.ImageScanner;
import net.sourceforge.zbar.Image;
import net.sourceforge.zbar.Symbol;
import net.sourceforge.zbar.SymbolSet;
import net.sourceforge.zbar.Config;
import android.graphics.YuvImage;
import com.dinect.checker.R;
import com.dinect.checker.view.CameraPreview;
public class CameraActivity extends Activity {
public class CameraActivity extends AppCompatActivity {
private Camera mCamera;
private SurfaceView mPreview;
private Handler autoFocusHandler;
private Handler mAutoFocusHandler;
private ImageScanner mScanner;
private HashMap<String, Integer> mContours = new HashMap<>();
ImageScanner scanner;
private boolean barcodeScanned = false;
private boolean mBarcodeScanned = false;
private boolean previewing = true;
static {
@@ -49,28 +56,37 @@ public class CameraActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.a_scanner);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
autoFocusHandler = new Handler();
mAutoFocusHandler = new Handler();
mCamera = getCameraInstance();
mScanner = new ImageScanner();
/* Instance barcode scanner */
scanner = new ImageScanner();
scanner.setConfig(0, Config.X_DENSITY, 3);
scanner.setConfig(0, Config.Y_DENSITY, 3);
SurfaceView preview = (SurfaceView) findViewById(R.id.cameraPreview);
SurfaceHolder holder = preview.getHolder();
mPreview = (SurfaceView) findViewById(R.id.cameraPreview);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setTitle(getString(R.string.scanner_title));
actionBar.setDisplayHomeAsUpEnabled(true);
}
SurfaceHolder holder = mPreview.getHolder();
holder.addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {
try {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
mCamera.setPreviewCallback(previewCallback);
mCamera.autoFocus(autoFocusCB);
mCamera.setDisplayOrientation(90);
initCountours();
} catch (Exception e) {
e.printStackTrace();
}
@@ -78,7 +94,6 @@ public class CameraActivity extends Activity {
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
mCamera.setDisplayOrientation(270);
}
@Override
@@ -88,6 +103,31 @@ public class CameraActivity extends Activity {
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu);
return true;
}
private void initCountours() {
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
int width = displayMetrics.widthPixels;
Resources res = getResources();
mContours.put("left", (int) res.getDimension(R.dimen.scanner_contour_top));
mContours.put("top", (int) res.getDimension(R.dimen.scanner_contour_left));
mContours.put("width", (int) res.getDimension(R.dimen.scanner_contour_height));
mContours.put("height", width - (2 * (int) res.getDimension(R.dimen.scanner_contour_left)));
Log.d("kifio", "left: " + mContours.get("left"));
Log.d("kifio", "top: " + mContours.get("top"));
Log.d("kifio", "width: " + mContours.get("width"));
Log.d("kifio", "height: " + mContours.get("height"));
}
public void onPause() {
super.onPause();
releaseCamera();
@@ -121,22 +161,24 @@ public class CameraActivity extends Activity {
PreviewCallback previewCallback = new PreviewCallback() {
public void onPreviewFrame(byte[] data, Camera camera) {
Camera.Parameters parameters = camera.getParameters();
Parameters parameters = camera.getParameters();
Size size = parameters.getPreviewSize();
Image barcode = new Image(size.width, size.height, "Y800");
barcode.setData(data);
// barcode.setCrop(mContours.get("left"), mContours.get("top"), mContours.get("width"), mContours.get("height"));
int result = scanner.scanImage(barcode);
int result = mScanner.scanImage(barcode);
if (result != 0) {
previewing = false;
mCamera.setPreviewCallback(null);
mCamera.stopPreview();
SymbolSet syms = scanner.getResults();
SymbolSet syms = mScanner.getResults();
for (Symbol sym : syms) {
barcodeScanned = true;
mBarcodeScanned = true;
Toast.makeText(CameraActivity.this, sym.getData(), Toast.LENGTH_SHORT).show();
}
}
@@ -146,7 +188,7 @@ public class CameraActivity extends Activity {
// Mimic continuous auto-focusing
AutoFocusCallback autoFocusCB = new AutoFocusCallback() {
public void onAutoFocus(boolean success, Camera camera) {
autoFocusHandler.postDelayed(doAutoFocus, 1000);
mAutoFocusHandler.postDelayed(doAutoFocus, 1000);
}
};
}

View File

@@ -1,85 +0,0 @@
package com.dinect.checker.view;
import java.io.IOException;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.Surface;
import android.view.SurfaceView;
import android.view.SurfaceHolder;
import android.content.Context;
import android.hardware.Camera;
import android.hardware.Camera.PreviewCallback;
import android.hardware.Camera.AutoFocusCallback;
import android.hardware.Camera.Parameters;
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
private PreviewCallback previewCallback;
private AutoFocusCallback autoFocusCallback;
public CameraPreview(Context context, Camera camera,
PreviewCallback previewCb,
AutoFocusCallback autoFocusCb) {
super(context);
mCamera = camera;
previewCallback = previewCb;
autoFocusCallback = autoFocusCb;
mHolder = getHolder();
mHolder.addCallback(this);
// deprecated setting, but required on Android versions prior to 3.0
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, now tell the camera where to draw the preview.
try {
mCamera.setPreviewDisplay(holder);
} catch (IOException e) {
Log.d("DBG", "Error setting camera preview: " + e.getMessage());
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
// Camera preview released in activity
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
/*
* If your preview can change or rotate, take care of those events here.
* Make sure to stop the preview before resizing or reformatting it.
*/
if (mHolder.getSurface() == null){
// preview surface does not exist
return;
}
// stop preview before making changes
try {
mCamera.stopPreview();
} catch (Exception e){
// ignore: tried to stop a non-existent preview
}
try {
// Hard code camera surface rotation 90 degs to match Activity view in portrait
mCamera.setDisplayOrientation(90);
mCamera.setPreviewDisplay(mHolder);
mCamera.setPreviewCallback(previewCallback);
mCamera.startPreview();
mCamera.autoFocus(autoFocusCallback);
} catch (Exception e){
Log.d("DBG", "Error starting camera preview: " + e.getMessage());
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 413 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 394 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 419 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 385 B

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_pressed="true"><shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="4dp"/>
<solid android:color="#3078c0"/>
</shape>
</item>
<item>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="4dp"/>
<solid android:color="#4272e7"/>
</shape>
</item>
</selector>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<gradient android:type="linear"
android:angle="90"
android:startColor="#00000000"
android:endColor="#36000000"/>
</shape>

View File

@@ -2,7 +2,7 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/rootLayout"
android:background="@android:color/white"
android:background="#404040"
android:layout_width="match_parent"
android:layout_height="match_parent">
@@ -10,5 +10,89 @@
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<View android:layout_height="178dp"
android:layout_width="match_parent"
android:background="#404040"/>
<!--<View android:layout_width="match_parent"-->
<!--android:layout_height="6dp"-->
<!--android:layout_marginTop="178dp"-->
<!--android:background="#c0000000"/>-->
<!--<View android:layout_width="24dp"-->
<!--android:layout_height="232dp"-->
<!--android:layout_marginTop="184dp"-->
<!--android:layout_gravity="left"-->
<!--android:background="#c0000000"/>-->
<!--<View android:layout_width="24dp"-->
<!--android:layout_height="232dp"-->
<!--android:layout_marginTop="184dp"-->
<!--android:layout_gravity="right"-->
<!--android:background="#c0000000"/>-->
<!--<View android:layout_width="match_parent"-->
<!--android:layout_height="18dp"-->
<!--android:layout_marginTop="416dp"-->
<!--android:background="#c0000000"/>-->
<View android:layout_height="match_parent"
android:layout_width="match_parent"
android:layout_marginTop="434dp"
android:background="#404040"/>
<!--<FrameLayout android:id="@+id/scanner_contour"-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="200dp"-->
<!--android:layout_marginTop="196dp"-->
<!--android:layout_marginLeft="36dp"-->
<!--android:layout_marginRight="36dp">-->
<!--<View android:layout_width="20dp"-->
<!--android:layout_height="20dp"-->
<!--android:layout_gravity="top|left"-->
<!--android:background="@drawable/shape_top_left"/>-->
<!--<View android:layout_width="20dp"-->
<!--android:layout_height="20dp"-->
<!--android:layout_gravity="top|right"-->
<!--android:background="@drawable/shape_top_right"/>-->
<!--<View android:layout_width="20dp"-->
<!--android:layout_height="20dp"-->
<!--android:layout_gravity="bottom|left"-->
<!--android:background="@drawable/shape_bottom_left"/>-->
<!--<View android:layout_width="20dp"-->
<!--android:layout_height="20dp"-->
<!--android:layout_gravity="bottom|right"-->
<!--android:background="@drawable/shape_bottom_right"/>-->
<!--</FrameLayout>-->
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#4272e7"
app:titleTextColor="@android:color/white"/>
<View android:id="@+id/toolbarShadow"
android:layout_width="match_parent"
android:layout_height="4dp"
android:layout_marginTop="?attr/actionBarSize"
android:background="@drawable/shadow_bottom"/>
<Button android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="48dp"
android:paddingLeft="60dp"
android:paddingRight="60dp"
android:text="@string/scan"
android:textAllCaps="true"
android:layout_gravity="center_horizontal|bottom"
android:layout_marginBottom="46dp"
android:background="@drawable/button_blue"/>
</FrameLayout>

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/faq"
android:orderInCategory="0"
android:title="@string/faq"
android:icon="@drawable/help_outline"
app:showAsAction="ifRoom"/>
<item android:id="@+id/logout"
android:orderInCategory="1"
android:title="@string/logout"
android:icon="@drawable/logout"
app:showAsAction="ifRoom"/>
</menu>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 544 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 442 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 721 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

View File

@@ -0,0 +1,5 @@
<resources>
<dimen name="scanner_contour_left">24dp</dimen>
<dimen name="scanner_contour_top">178dp</dimen>
<dimen name="scanner_contour_height">232dp</dimen>
</resources>

View File

@@ -0,0 +1,7 @@
<resources>
<string name="app_name">Checker</string>
<string name="scanner_title">Сканнер карты</string>
<string name="scan">Сканировать</string>
<string name="faq">FAQ</string>
<string name="logout">Выход</string>
</resources>

View File

@@ -0,0 +1,6 @@
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.NoActionBar"/>
</resources>

View File

@@ -15,7 +15,7 @@ class _RegistrationScreenState extends BaseState<FinishRegistrationScreen> {
AppBar _getAppBar() {
return new AppBar(title: new Text("Регистрация магазина"),
backgroundColor: const Color(0xff4272e7), actions: <Widget>[
backgroundColor: const Color(primaryColor), actions: <Widget>[
new IconButton(
icon: new Icon(Icons.help_outline),
tooltip: 'Air it',

View File

@@ -21,6 +21,9 @@ const String splash_png = 'assets/splash.png';
const String logout_png = 'assets/logout.png';
const String activate_token_bg_png = 'assets/activate_token_message_background.png';
// Colors
const int primaryColor = 0xffeb0004;
final httpClient = createHttpClient();
void main() {
@@ -64,7 +67,7 @@ startScanner() async{
/// Навигация по приложению.
/// widget - следующий экран приложения.
pushRoute(BuildContext context, Widget widget) {
Navigator.of(context).push(new MaterialPageRoute<Null>(
Navigator.of(context).pushReplacement(new MaterialPageRoute<Null>(
builder: (BuildContext context) {
return widget;
}));

View File

@@ -19,17 +19,12 @@ class _RegistrationScreenState extends BaseState<RegistrationScreen> {
}
AppBar _getAppBar() {
return new AppBar(title: new Text("Регистрация магазина"),
backgroundColor: const Color(0xff4272e7), actions: <Widget>[
return new AppBar(title: new Text("Регистрация"),
backgroundColor: const Color(primaryColor), actions: <Widget>[
new IconButton(
icon: new Icon(Icons.help_outline),
tooltip: 'Air it',
onPressed: faq,
),
new IconButton(
icon: new Image(height: 24.0, width: 24.0, image: new AssetImage('assets/logout.png')),
tooltip: 'Restitch it',
onPressed: logout,
)
]);
}

View File

@@ -16,7 +16,7 @@ class SplashScreen extends StatelessWidget {
_showNextScreen(context);
});
return new Image.asset(logo_png, fit: BoxFit.cover);
return new Image.asset(splash_png, fit: BoxFit.cover);
}
/// Запуск следующего экрана приложения.