Исправления на экране сканера

This commit is contained in:
Ivan Murashov
2017-07-27 13:35:27 +03:00
parent d0b5b17334
commit 303f3e2ff3
12 changed files with 165 additions and 56 deletions

View File

@@ -49,4 +49,6 @@ dependencies {
compile fileTree(dir: 'libs', include: ['*.jar']) compile fileTree(dir: 'libs', include: ['*.jar'])
compile "com.google.android.gms:play-services-gcm:11.0.1" compile "com.google.android.gms:play-services-gcm:11.0.1"
compile 'com.android.support:appcompat-v7:25.0.0' compile 'com.android.support:appcompat-v7:25.0.0'
compile 'com.squareup.okhttp3:okhttp:3.8.1'
compile 'com.squareup.okio:okio:1.13.0'
} }

View File

@@ -1,7 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.dinect.checker" package="com.dinect.checker"
android:versionCode="1" android:versionCode="1"
android:versionName="0.0.2"> android:versionName="0.0.3">
<uses-sdk android:minSdkVersion="16" android:targetSdkVersion="21" /> <uses-sdk android:minSdkVersion="16" android:targetSdkVersion="21" />

View File

@@ -46,11 +46,17 @@ import android.view.SurfaceHolder;
import android.view.SurfaceView; import android.view.SurfaceView;
import java.io.IOException; import java.io.IOException;
import java.lang.Exception; import java.lang.Exception;
import java.lang.Thread;
import java.util.List; import java.util.List;
import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel; import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler; import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result; import io.flutter.plugin.common.MethodChannel.Result;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.json.*;
import com.dinect.checker.R; import com.dinect.checker.R;
public class CameraActivity extends AppCompatActivity implements SurfaceHolder.Callback { public class CameraActivity extends AppCompatActivity implements SurfaceHolder.Callback {
@@ -61,9 +67,10 @@ public class CameraActivity extends AppCompatActivity implements SurfaceHolder.C
private HashMap<String, Integer> mContours = new HashMap<>(); private HashMap<String, Integer> mContours = new HashMap<>();
private boolean mBarcodeScanned = false; private boolean mBarcodeScanned = false;
private boolean previewing = false; private boolean previewing = true;
private Handler autoFocusHandler; private Handler autoFocusHandler;
private int mOffset; private int mOffset;
private String mToken = "19305da6610a74504f8a462411199b5de0c93979";
static { static {
System.loadLibrary("iconv"); System.loadLibrary("iconv");
@@ -254,17 +261,61 @@ public class CameraActivity extends AppCompatActivity implements SurfaceHolder.C
mCamera.stopPreview(); mCamera.stopPreview();
SymbolSet syms = mScanner.getResults(); SymbolSet syms = mScanner.getResults();
for (Symbol sym : syms) { for (Symbol sym : syms) {
mBarcodeScanned = true; mBarcodeScanned = true;
Intent intent = new Intent(); requestUser(sym.getData());
intent.putExtra("code", sym.getData()); break;
setResult(RESULT_OK, intent);
finish();
} }
} }
} }
}; };
private NetworkThread t;
private void requestUser(String code) {
t = new NetworkThread(this, code, mToken);
t.start();
}
void handleResult(Response response, String card) {
if (response == null) {
previewing = true;
mCamera.setPreviewCallback(previewCallback);
mCamera.startPreview();
return;
}
if (response.code() == 200) {
try {
JSONArray users = new JSONArray(response.body().string());
if (users.length() > 0) {
Toast.makeText(this, "Чики-брики и в дамки", Toast.LENGTH_SHORT).show();
Intent intent = new Intent();
intent.putExtra("user", users.get(0).toString());
intent.putExtra("card", card);
setResult(RESULT_OK, intent);
finish();
} else {
Toast.makeText(this, "Пользователь с таким id не найден", Toast.LENGTH_SHORT).show();
previewing = true;
mCamera.setPreviewCallback(previewCallback);
mCamera.startPreview();
}
} catch (IOException | JSONException e) {
e.printStackTrace();
}
} else {
try {
Log.d("kifio", response.body().string());
Toast.makeText(this, "Произошла ошибка", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
e.printStackTrace();
}
}
t.close();
}
private Runnable doAutoFocus = new Runnable() { private Runnable doAutoFocus = new Runnable() {
public void run() { public void run() {
if (previewing) { if (previewing) {
@@ -273,10 +324,60 @@ public class CameraActivity extends AppCompatActivity implements SurfaceHolder.C
} }
}; };
AutoFocusCallback autoFocusCallback = new AutoFocusCallback() { AutoFocusCallback autoFocusCallback = new AutoFocusCallback() {
public void onAutoFocus(boolean success, Camera camera) { public void onAutoFocus(boolean success, Camera camera) {
Log.d("kifio", String.valueOf(success));
autoFocusHandler.postDelayed(doAutoFocus, 1000); autoFocusHandler.postDelayed(doAutoFocus, 1000);
} }
}; };
private static class NetworkThread extends Thread {
private CameraActivity mActivity;
private String mCode = "";
private String mUrl = "http://pos-api-int.dinect.com/20130701/users/?auto=";
private String mCard = "";
private String mToken = "";
NetworkThread(final CameraActivity activity, final String code, String token) {
if (code == null) {
activity.runOnUiThread(new Runnable() {
public void run() {
activity.handleResult(null, code);
}
});
} else {
mActivity = activity;
mCard = code;
mUrl += code;
mToken = token;
}
}
@Override
public void run() {
Request request = new Request.Builder()
.addHeader("DM-Authorization", "dmapptoken 9fec83cdca38c357e6b65dbb17514cdd36bf2a08")
.addHeader("Authorization", "dmtoken " + mToken)
.url(mUrl)
.build();
try {
OkHttpClient client = new OkHttpClient();
final Response response = client.newCall(request).execute();
mActivity.runOnUiThread(new Runnable() {
public void run() {
mActivity.handleResult(response, mCard);
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
void close() {
mActivity = null;
}
}
} }

View File

@@ -15,6 +15,7 @@ import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result; import io.flutter.plugin.common.MethodChannel.Result;
import com.google.android.gms.iid.InstanceID; import com.google.android.gms.iid.InstanceID;
import java.util.Map; import java.util.Map;
import java.util.ArrayList;
import java.lang.System; import java.lang.System;
public class MainActivity extends FlutterActivity { public class MainActivity extends FlutterActivity {
@@ -109,9 +110,13 @@ public class MainActivity extends FlutterActivity {
finish(); finish();
} else if (requestCode == START_SCANNER_REQUEST_CODE && resultCode == RESULT_OK) { } else if (requestCode == START_SCANNER_REQUEST_CODE && resultCode == RESULT_OK) {
if (data != null) { if (data != null) {
String code = data.getExtras().getString("code", null); String user = data.getExtras().getString("user", null);
if (code != null) { if (user != null) {
mChannel.invokeMethod("purchase", code); String card = data.getExtras().getString("card", null);
ArrayList<String> args = new ArrayList<>(2);
args.add(user);
args.add(card);
mChannel.invokeMethod("purchase", args);
} else { } else {
String menuItem = data.getExtras().getString("item", null); String menuItem = data.getExtras().getString("item", null);
Log.d("item", menuItem); Log.d("item", menuItem);

View File

@@ -44,7 +44,7 @@ class _RegistrationScreenState extends BaseState<FinishRegistrationScreen> {
if (_tokenActive) { if (_tokenActive) {
startScanner(context); startScanner(context);
} else { } else {
checkTokenStatus(context).then((response) { checkTokenStatus(token).then((response) {
print(response.body); print(response.body);
Map parsedMap = JSON.decode(response.body); Map parsedMap = JSON.decode(response.body);

View File

@@ -27,7 +27,7 @@ abstract class BaseState<T> extends State<T> {
} }
getFaqButton() { getFaqButton() {
return new IconButton(icon: new Icon(Icons.help_outline), onPressed: () => faq(context)); return new IconButton(icon: new Icon(Icons.help_outline), onPressed: () => faq(context, false));
} }
getLogoutButton() { getLogoutButton() {

View File

@@ -2,6 +2,7 @@ import 'package:flutter/services.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'network.dart'; import 'network.dart';
import 'registration.dart';
import 'purchase.dart'; import 'purchase.dart';
import 'faq.dart'; import 'faq.dart';
@@ -18,8 +19,8 @@ pushRoute(BuildContext context, Widget widget) {
} }
// Добавление route, с возможностью вернуться к предыдущему экрану. // Добавление route, с возможностью вернуться к предыдущему экрану.
faq(BuildContext context) { faq(BuildContext context, bool returnToScanner) {
var route = new MaterialPageRoute<Null>(builder: (BuildContext context) => new FAQScreen()); var route = new MaterialPageRoute<Null>(builder: (BuildContext context) => new FAQScreen(returnToScanner));
Navigator.of(context).push(route); Navigator.of(context).push(route);
} }
@@ -28,9 +29,9 @@ logout(BuildContext context) {
VoidCallback positiveCalback = () { VoidCallback positiveCalback = () {
if (token != null) { if (token != null) {
deleteToken(token).then((response) async { deleteToken(token).then((response) {
print(response.body); print(response.body);
await platform.invokeMethod('removeKeys'); platform.invokeMethod('removeKeys');
pushRoute(context, new RegistrationScreen()); // Запускаем регистрацию pushRoute(context, new RegistrationScreen()); // Запускаем регистрацию
}).catchError((error) { }).catchError((error) {
print(error.toString()); print(error.toString());
@@ -57,35 +58,14 @@ startScanner(BuildContext context) async {
if (call.method == 'logout') { if (call.method == 'logout') {
logout(context); logout(context);
} else if (call.method == 'faq') { } else if (call.method == 'faq') {
faq(context); faq(context, true);
} else { } else {
String userString = call.arguments[0];
List usersList = JSON.decode(call.arguments); print('user: ${userString}');
print('usersList.length: ${usersList.length}'); String card = call.arguments[1];
if (usersList.length > 0) { print('card: ${card}');
pushRoute(context, new PurchaseScreen(usersList[0], card)); var route = new MaterialPageRoute<Null>(builder: (BuildContext context) => new PurchaseScreen(userString, card));
} Navigator.of(context).pushReplacement(route);
// var card = ;
// String url = 'http://pos-api-int.dinect.com/20130701/users/?auto=${card}';
// print('url: ' + url);
// var headers = {
// 'DM-Authorization': 'dmapptoken 9fec83cdca38c357e6b65dbb17514cdd36bf2a08',
// 'Authorization': 'dmtoken ${token}'
// };
// httpClient.get(url, headers: headers).then((response) {
// print(response.body);
// }).catchError((error) {
// print(error.toString());
// });
} }
}); });
} }

View File

@@ -3,6 +3,7 @@ import 'package:flutter/services.dart';
import 'base_state.dart'; import 'base_state.dart';
import 'consts.dart'; import 'consts.dart';
import 'common.dart';
/// Класс содержит заголовки и текст блоков FAQ. /// Класс содержит заголовки и текст блоков FAQ.
class Entry { class Entry {
@@ -35,11 +36,18 @@ class EntryItem extends StatelessWidget {
} }
class FAQScreen extends StatefulWidget { class FAQScreen extends StatefulWidget {
@override State createState() => new FAQScreenState<FAQScreen>();
FAQScreen(this.b);
bool b;
@override State createState() => new FAQScreenState<FAQScreen>(b);
} }
class FAQScreenState<T> extends BaseState<FAQScreen> { class FAQScreenState<T> extends BaseState<FAQScreen> {
FAQScreenState(this.returnToScanner);
bool returnToScanner;
@override String getTitle() { @override String getTitle() {
return "FAQ"; return "FAQ";
} }
@@ -50,9 +58,17 @@ class FAQScreenState<T> extends BaseState<FAQScreen> {
/// Метод возвращает ListView с блоками faq. /// Метод возвращает ListView с блоками faq.
@override Widget getScreenContent() { @override Widget getScreenContent() {
return new ListView.builder( return new WillPopScope(onWillPop: onWillPop, child: new ListView.builder(
itemBuilder: (BuildContext context, int index) => new EntryItem(data[index]), itemBuilder: (BuildContext context, int index) => new EntryItem(data[index]),
itemCount: data.length); itemCount: data.length));
}
onWillPop() {
if(returnToScanner) {
return startScanner(context);
} else {
return true;
}
} }
/// Список с контентом /// Список с контентом
@@ -67,7 +83,7 @@ class FAQScreenState<T> extends BaseState<FAQScreen> {
Введите DIN код магазина (выдается партнером/менеджером International Auto Club, дублируется на почту) Введите DIN код магазина (выдается партнером/менеджером International Auto Club, дублируется на почту)
Нажать кнопку: «Зарегистрировать» Нажать кнопку: «Зарегистрировать»
Дождитесь подтверждение активации программы, нажатием кнопки “Обновите статус активации” обновите статус. Дождитесь подтверждение активации программы, нажатием кнопки “Обновите статус активации” обновите статус.
После подтверждения запроса на активацию программы Партнером/менеджером нажмите кнопку “Завершить регистрацию”, приложение готово к использованию. После подтверждения запроса на активацию программы Партнером/менеджером нажмите кнопкиопку “Завершить регистрацию”, приложение готово к использованию.
В случае желания изменить номер кассы, необходимо нажать на “значек” верхнем правом углу и вернуться на шаг регистрации.'''; В случае желания изменить номер кассы, необходимо нажать на “значек” верхнем правом углу и вернуться на шаг регистрации.''';

View File

@@ -31,7 +31,7 @@ checkTokenStatus(String token) async {
deleteToken(String token) async { deleteToken(String token) async {
String url = intUrl + 'tokens/' + token + '?_dmapptoken=' + intToken; String url = intUrl + 'tokens/' + token + '?_dmapptoken=' + intToken;
print(url); print(url);
return httpClient.delete(url).then(); return httpClient.delete(url);
} }
// Удалить токены // Удалить токены

View File

@@ -4,24 +4,27 @@ import 'dart:convert';
import 'dart:async'; import 'dart:async';
import 'main.dart'; import 'main.dart';
import 'common.dart';
import 'consts.dart';
import 'network.dart';
import 'base_state.dart'; import 'base_state.dart';
import 'purchase_success.dart'; import 'purchase_success.dart';
/// Экран проведения покупки. /// Экран проведения покупки.
class PurchaseScreen extends StatefulWidget { class PurchaseScreen extends StatefulWidget {
PurchaseScreen(this.response, this.card); PurchaseScreen(this.user, this.card);
Map response; String user;
String card; String card;
@override State createState() => new PurchaseScreenState<PurchaseScreen>(response, card); @override State createState() => new PurchaseScreenState<PurchaseScreen>(user, card);
} }
class PurchaseScreenState<T> extends BaseState<PurchaseScreen> { class PurchaseScreenState<T> extends BaseState<PurchaseScreen> {
PurchaseScreenState(Map user, String card) { PurchaseScreenState(String userString, String card) {
this.user = user; this.user = JSON.decode(userString);
this.card = card; this.card = card;
getLoyality(user['loyalty_url']); getLoyality(user['loyalty_url']);
} }

View File

@@ -2,6 +2,8 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'main.dart'; import 'main.dart';
import 'common.dart';
import 'consts.dart';
import 'base_state.dart'; import 'base_state.dart';
import 'purchase.dart'; import 'purchase.dart';

View File

@@ -81,9 +81,9 @@ class SplashScreen extends StatelessWidget {
if (response.statusCode == 409) { if (response.statusCode == 409) {
pushRoute(context, new FinishRegistrationScreen()); pushRoute(context, new FinishRegistrationScreen());
} else { } else {
deleteToken(token).then((response) async { deleteToken(token).then((response) {
print(response.body); print(response.body);
await platform.invokeMethod('removeKeys'); platform.invokeMethod('removeKeys');
Navigator.of(context).pop(); // Убираем текущий route Navigator.of(context).pop(); // Убираем текущий route
pushRoute(context, new RegistrationScreen()); // Запускаем регистрацию pushRoute(context, new RegistrationScreen()); // Запускаем регистрацию
}).catchError((error) { }).catchError((error) {