diff --git a/android/app/build.gradle b/android/app/build.gradle index 6b73299..30d806e 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -49,4 +49,6 @@ dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile "com.google.android.gms:play-services-gcm:11.0.1" 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' } diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 3f05bdb..66f6f5e 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -1,7 +1,7 @@ + android:versionName="0.0.3"> diff --git a/android/app/src/main/java/com/dinect/checker/activity/CameraActivity.java b/android/app/src/main/java/com/dinect/checker/activity/CameraActivity.java index 77adbcd..4411cc0 100644 --- a/android/app/src/main/java/com/dinect/checker/activity/CameraActivity.java +++ b/android/app/src/main/java/com/dinect/checker/activity/CameraActivity.java @@ -46,11 +46,17 @@ import android.view.SurfaceHolder; import android.view.SurfaceView; import java.io.IOException; import java.lang.Exception; +import java.lang.Thread; import java.util.List; import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodChannel; import io.flutter.plugin.common.MethodChannel.MethodCallHandler; import io.flutter.plugin.common.MethodChannel.Result; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import org.json.*; + import com.dinect.checker.R; public class CameraActivity extends AppCompatActivity implements SurfaceHolder.Callback { @@ -61,9 +67,10 @@ public class CameraActivity extends AppCompatActivity implements SurfaceHolder.C private HashMap mContours = new HashMap<>(); private boolean mBarcodeScanned = false; - private boolean previewing = false; + private boolean previewing = true; private Handler autoFocusHandler; private int mOffset; + private String mToken = "19305da6610a74504f8a462411199b5de0c93979"; static { System.loadLibrary("iconv"); @@ -254,17 +261,61 @@ public class CameraActivity extends AppCompatActivity implements SurfaceHolder.C mCamera.stopPreview(); SymbolSet syms = mScanner.getResults(); + for (Symbol sym : syms) { mBarcodeScanned = true; - Intent intent = new Intent(); - intent.putExtra("code", sym.getData()); - setResult(RESULT_OK, intent); - finish(); + requestUser(sym.getData()); + break; } } } }; + 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() { public void run() { if (previewing) { @@ -273,10 +324,60 @@ public class CameraActivity extends AppCompatActivity implements SurfaceHolder.C } }; - AutoFocusCallback autoFocusCallback = new AutoFocusCallback() { public void onAutoFocus(boolean success, Camera camera) { + Log.d("kifio", String.valueOf(success)); 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; + } + } } \ No newline at end of file diff --git a/android/app/src/main/java/com/dinect/checker/activity/MainActivity.java b/android/app/src/main/java/com/dinect/checker/activity/MainActivity.java index 95a0c33..dec6647 100644 --- a/android/app/src/main/java/com/dinect/checker/activity/MainActivity.java +++ b/android/app/src/main/java/com/dinect/checker/activity/MainActivity.java @@ -15,6 +15,7 @@ import io.flutter.plugin.common.MethodChannel.MethodCallHandler; import io.flutter.plugin.common.MethodChannel.Result; import com.google.android.gms.iid.InstanceID; import java.util.Map; +import java.util.ArrayList; import java.lang.System; public class MainActivity extends FlutterActivity { @@ -109,9 +110,13 @@ public class MainActivity extends FlutterActivity { finish(); } else if (requestCode == START_SCANNER_REQUEST_CODE && resultCode == RESULT_OK) { if (data != null) { - String code = data.getExtras().getString("code", null); - if (code != null) { - mChannel.invokeMethod("purchase", code); + String user = data.getExtras().getString("user", null); + if (user != null) { + String card = data.getExtras().getString("card", null); + ArrayList args = new ArrayList<>(2); + args.add(user); + args.add(card); + mChannel.invokeMethod("purchase", args); } else { String menuItem = data.getExtras().getString("item", null); Log.d("item", menuItem); diff --git a/lib/activate_token.dart b/lib/activate_token.dart index 42ca4df..f19cb9f 100644 --- a/lib/activate_token.dart +++ b/lib/activate_token.dart @@ -44,7 +44,7 @@ class _RegistrationScreenState extends BaseState { if (_tokenActive) { startScanner(context); } else { - checkTokenStatus(context).then((response) { + checkTokenStatus(token).then((response) { print(response.body); Map parsedMap = JSON.decode(response.body); diff --git a/lib/base_state.dart b/lib/base_state.dart index 3c156eb..ea95cfa 100644 --- a/lib/base_state.dart +++ b/lib/base_state.dart @@ -27,7 +27,7 @@ abstract class BaseState extends State { } 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() { diff --git a/lib/common.dart b/lib/common.dart index c4e83c7..3520066 100644 --- a/lib/common.dart +++ b/lib/common.dart @@ -2,6 +2,7 @@ import 'package:flutter/services.dart'; import 'package:flutter/material.dart'; import 'network.dart'; +import 'registration.dart'; import 'purchase.dart'; import 'faq.dart'; @@ -18,8 +19,8 @@ pushRoute(BuildContext context, Widget widget) { } // Добавление route, с возможностью вернуться к предыдущему экрану. -faq(BuildContext context) { - var route = new MaterialPageRoute(builder: (BuildContext context) => new FAQScreen()); +faq(BuildContext context, bool returnToScanner) { + var route = new MaterialPageRoute(builder: (BuildContext context) => new FAQScreen(returnToScanner)); Navigator.of(context).push(route); } @@ -28,9 +29,9 @@ logout(BuildContext context) { VoidCallback positiveCalback = () { if (token != null) { - deleteToken(token).then((response) async { + deleteToken(token).then((response) { print(response.body); - await platform.invokeMethod('removeKeys'); + platform.invokeMethod('removeKeys'); pushRoute(context, new RegistrationScreen()); // Запускаем регистрацию }).catchError((error) { print(error.toString()); @@ -57,35 +58,14 @@ startScanner(BuildContext context) async { if (call.method == 'logout') { logout(context); } else if (call.method == 'faq') { - faq(context); + faq(context, true); } else { - - List usersList = JSON.decode(call.arguments); - print('usersList.length: ${usersList.length}'); - if (usersList.length > 0) { - pushRoute(context, new PurchaseScreen(usersList[0], card)); - } - - - // 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()); - // }); - + String userString = call.arguments[0]; + print('user: ${userString}'); + String card = call.arguments[1]; + print('card: ${card}'); + var route = new MaterialPageRoute(builder: (BuildContext context) => new PurchaseScreen(userString, card)); + Navigator.of(context).pushReplacement(route); } }); } diff --git a/lib/faq.dart b/lib/faq.dart index 8bba250..62183fc 100644 --- a/lib/faq.dart +++ b/lib/faq.dart @@ -3,6 +3,7 @@ import 'package:flutter/services.dart'; import 'base_state.dart'; import 'consts.dart'; +import 'common.dart'; /// Класс содержит заголовки и текст блоков FAQ. class Entry { @@ -35,11 +36,18 @@ class EntryItem extends StatelessWidget { } class FAQScreen extends StatefulWidget { - @override State createState() => new FAQScreenState(); + + FAQScreen(this.b); + bool b; + + @override State createState() => new FAQScreenState(b); } class FAQScreenState extends BaseState { + FAQScreenState(this.returnToScanner); + bool returnToScanner; + @override String getTitle() { return "FAQ"; } @@ -50,9 +58,17 @@ class FAQScreenState extends BaseState { /// Метод возвращает ListView с блоками faq. @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]), - itemCount: data.length); + itemCount: data.length)); + } + + onWillPop() { + if(returnToScanner) { + return startScanner(context); + } else { + return true; + } } /// Список с контентом @@ -67,7 +83,7 @@ class FAQScreenState extends BaseState { Введите DIN код магазина (выдается партнером/менеджером International Auto Club, дублируется на почту) Нажать кнопку: «Зарегистрировать» Дождитесь подтверждение активации программы, нажатием кнопки “Обновите статус активации” обновите статус. - После подтверждения запроса на активацию программы Партнером/менеджером нажмите кнопку “Завершить регистрацию”, приложение готово к использованию. + После подтверждения запроса на активацию программы Партнером/менеджером нажмите кнопкиопку “Завершить регистрацию”, приложение готово к использованию. В случае желания изменить номер кассы, необходимо нажать на “значек” верхнем правом углу и вернуться на шаг регистрации.'''; diff --git a/lib/network.dart b/lib/network.dart index bd41282..7e1d7a9 100644 --- a/lib/network.dart +++ b/lib/network.dart @@ -31,7 +31,7 @@ checkTokenStatus(String token) async { deleteToken(String token) async { String url = intUrl + 'tokens/' + token + '?_dmapptoken=' + intToken; print(url); - return httpClient.delete(url).then(); + return httpClient.delete(url); } // Удалить токены diff --git a/lib/purchase.dart b/lib/purchase.dart index 7ea43f3..c2e4864 100644 --- a/lib/purchase.dart +++ b/lib/purchase.dart @@ -4,24 +4,27 @@ import 'dart:convert'; import 'dart:async'; import 'main.dart'; +import 'common.dart'; +import 'consts.dart'; +import 'network.dart'; import 'base_state.dart'; import 'purchase_success.dart'; /// Экран проведения покупки. class PurchaseScreen extends StatefulWidget { - PurchaseScreen(this.response, this.card); + PurchaseScreen(this.user, this.card); - Map response; + String user; String card; - @override State createState() => new PurchaseScreenState(response, card); + @override State createState() => new PurchaseScreenState(user, card); } class PurchaseScreenState extends BaseState { - PurchaseScreenState(Map user, String card) { - this.user = user; + PurchaseScreenState(String userString, String card) { + this.user = JSON.decode(userString); this.card = card; getLoyality(user['loyalty_url']); } diff --git a/lib/purchase_success.dart b/lib/purchase_success.dart index 2903b02..c333ecf 100644 --- a/lib/purchase_success.dart +++ b/lib/purchase_success.dart @@ -2,6 +2,8 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'main.dart'; +import 'common.dart'; +import 'consts.dart'; import 'base_state.dart'; import 'purchase.dart'; diff --git a/lib/splash.dart b/lib/splash.dart index 69adcdb..ed41625 100644 --- a/lib/splash.dart +++ b/lib/splash.dart @@ -81,9 +81,9 @@ class SplashScreen extends StatelessWidget { if (response.statusCode == 409) { pushRoute(context, new FinishRegistrationScreen()); } else { - deleteToken(token).then((response) async { + deleteToken(token).then((response) { print(response.body); - await platform.invokeMethod('removeKeys'); + platform.invokeMethod('removeKeys'); Navigator.of(context).pop(); // Убираем текущий route pushRoute(context, new RegistrationScreen()); // Запускаем регистрацию }).catchError((error) {