Menu in iOS
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 117 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 25 KiB |
@@ -1,331 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2017 .
|
|
||||||
*
|
|
||||||
* 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 com.dinect.checker;
|
|
||||||
|
|
||||||
import android.app.AlertDialog;
|
|
||||||
import android.app.Dialog;
|
|
||||||
import android.app.DialogFragment;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.support.annotation.NonNull;
|
|
||||||
import android.support.annotation.Nullable;
|
|
||||||
import android.support.v7.app.ActionBar;
|
|
||||||
import android.support.v7.app.AppCompatActivity;
|
|
||||||
import android.support.v7.widget.Toolbar;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.util.Pair;
|
|
||||||
import android.view.KeyEvent;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.Menu;
|
|
||||||
import android.view.MenuItem;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.Window;
|
|
||||||
import android.widget.EditText;
|
|
||||||
import android.widget.FrameLayout;
|
|
||||||
import android.widget.TextView;
|
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import org.json.JSONArray;
|
|
||||||
import org.json.JSONException;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
import okhttp3.Call;
|
|
||||||
import okhttp3.Callback;
|
|
||||||
import okhttp3.Response;
|
|
||||||
import okhttp3.ResponseBody;
|
|
||||||
|
|
||||||
import com.dinect.checker.net.ApiClient;
|
|
||||||
import com.dinect.checker.StatedImageButton;
|
|
||||||
import com.dinect.checker.SearchType;
|
|
||||||
import com.dinect.checker.StatedImageButton.StatedImageButtonInteractorListener;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by anonymous
|
|
||||||
*/
|
|
||||||
|
|
||||||
public abstract class AbstractScannerActivity extends AppCompatActivity implements StatedImageButtonInteractorListener{
|
|
||||||
|
|
||||||
private final static String TAG = "Checker.ScannerActivity";
|
|
||||||
|
|
||||||
private int counter;
|
|
||||||
|
|
||||||
public static final String SCAN_MODES = "SCAN_MODES";
|
|
||||||
public static final String ERROR_INFO = "ERROR_INFO";
|
|
||||||
|
|
||||||
private ApiClient mClient;
|
|
||||||
private StatedImageButton statedImageButton;
|
|
||||||
|
|
||||||
boolean isCameraAvailable() {
|
|
||||||
Log.d(TAG, "isCameraAvailable");
|
|
||||||
PackageManager pm = getPackageManager();
|
|
||||||
return pm.hasSystemFeature(PackageManager.FEATURE_CAMERA);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void cancelRequest(final @NonNull String message) {
|
|
||||||
Log.d(TAG, "cancelRequest: " + message);
|
|
||||||
final Intent response = new Intent();
|
|
||||||
response.putExtra(ERROR_INFO, message);
|
|
||||||
setResult(RESULT_CANCELED, response);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
final String appToken = getIntent().getStringExtra(MainActivity.PREF_APP_TOKEN);
|
|
||||||
final String token = getIntent().getStringExtra(MainActivity.PREF_POS_TOKEN);
|
|
||||||
final String url = getIntent().getStringExtra(MainActivity.PREF_API_URL) + "/users/";
|
|
||||||
mClient = new ApiClient(url, appToken, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* initialize activity
|
|
||||||
* - removes windows title
|
|
||||||
* - set content view to layout id
|
|
||||||
*
|
|
||||||
* @param layoutID layout to use
|
|
||||||
*/
|
|
||||||
protected final boolean init(final int layoutID) {
|
|
||||||
Log.d(TAG, "init");
|
|
||||||
if (!isCameraAvailable()) {
|
|
||||||
// Cancel request if there is no rear-facing camera.
|
|
||||||
cancelRequest("Camera unavailable");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Hide the window title.
|
|
||||||
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
|
||||||
setContentView(layoutID);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configure toolbar of app
|
|
||||||
*/
|
|
||||||
protected final void initToolbar(Intent intent) {
|
|
||||||
|
|
||||||
final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
|
|
||||||
toolbar.setBackgroundColor((int) intent.getLongExtra(MainActivity.PREF_APP_BAR_COLOR, 0xffffff));
|
|
||||||
setSupportActionBar(toolbar);
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
final ActionBar actionBar = getSupportActionBar();
|
|
||||||
|
|
||||||
if (actionBar != null) {
|
|
||||||
actionBar.setTitle(null);
|
|
||||||
actionBar.setDisplayHomeAsUpEnabled(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
initManualInput();
|
|
||||||
initSwitchButton();
|
|
||||||
setupSecretClickHandler(toolbar);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initSwitchButton() {
|
|
||||||
statedImageButton = (StatedImageButton) findViewById(R.id.cardPhoneButton);
|
|
||||||
statedImageButton.setButtonState(SearchType.CARD);
|
|
||||||
statedImageButton.setStatedImageButtonInteractorListener(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStateChanged(SearchType searchType) {
|
|
||||||
Log.d(TAG, searchType.toString());
|
|
||||||
EditText manualInput = (EditText) findViewById(R.id.manual_input);
|
|
||||||
switch (searchType) {
|
|
||||||
case CARD:
|
|
||||||
manualInput.setHint(getIntent().getStringExtra("enter_manual"));
|
|
||||||
break;
|
|
||||||
case PHONE_NUMBER:
|
|
||||||
manualInput.setHint(getIntent().getStringExtra("enter_phone"));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initManualInput() {
|
|
||||||
EditText manualInput = (EditText) findViewById(R.id.manual_input);
|
|
||||||
|
|
||||||
// для удобства, чтоб не вводить постоянно руками при разработке
|
|
||||||
|
|
||||||
// manualInput.setText("9990010009012057060904229");
|
|
||||||
// manualInput.setText("4620011139016337050236302");
|
|
||||||
manualInput.setHint(getIntent().getStringExtra("enter_manual"));
|
|
||||||
|
|
||||||
manualInput.setOnEditorActionListener(new TextView.OnEditorActionListener() {
|
|
||||||
@Override
|
|
||||||
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
|
|
||||||
handleBarcode(v.getText().toString());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setupSecretClickHandler(final @NonNull View toolbar) {
|
|
||||||
// Configure increment handler
|
|
||||||
toolbar.setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View view) {
|
|
||||||
if (counter == 15) {
|
|
||||||
switchScanner();
|
|
||||||
} else {
|
|
||||||
counter++;
|
|
||||||
}
|
|
||||||
Log.d(TAG, "toolbar clicked " + counter + " times");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void switchScanner() {
|
|
||||||
|
|
||||||
final SharedPreferences prefs = getSharedPreferences("scanner", Context.MODE_PRIVATE);
|
|
||||||
|
|
||||||
int idx = (prefs.getInt(MainActivity.SCANNER_BACKEND_KEY, 0) == MainActivity.ZXING)
|
|
||||||
? MainActivity.ZBAR
|
|
||||||
: MainActivity.ZXING;
|
|
||||||
|
|
||||||
Log.d(TAG, "switch to scanner backend " + idx + ", " + MainActivity.SCANNER_BACKEND[idx].toString());
|
|
||||||
prefs.edit().putInt(MainActivity.SCANNER_BACKEND_KEY, idx).apply();
|
|
||||||
|
|
||||||
cancelRequest("Scanner backend changed");
|
|
||||||
setResult(RESULT_OK);
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds scanner view to target frame layout
|
|
||||||
*/
|
|
||||||
protected final void addScanner(final @NonNull View view, final int targetFrameId) {
|
|
||||||
Log.d(TAG, "addScanner");
|
|
||||||
final FrameLayout root = (FrameLayout) findViewById(targetFrameId);
|
|
||||||
root.addView(view, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract View initScanner();
|
|
||||||
|
|
||||||
public void handleBarcode(final @NonNull String searchString) {
|
|
||||||
mClient.findUser(searchString, statedImageButton.getCurrentState(), new Callback() {
|
|
||||||
@Override
|
|
||||||
public void onFailure(Call call, IOException e) {
|
|
||||||
handleFail(searchString);
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void onResponse(Call call, Response response) throws IOException {
|
|
||||||
try {
|
|
||||||
ResponseBody body = response.body();
|
|
||||||
if (body != null) {
|
|
||||||
switch (response.code()) {
|
|
||||||
case 200:
|
|
||||||
final JSONArray users = new JSONArray(body.string());
|
|
||||||
if (users.length() > 0) {
|
|
||||||
handleSuccess(searchString, users.get(0).toString());
|
|
||||||
} else {
|
|
||||||
handleFail(searchString);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 204:
|
|
||||||
handleFail(searchString);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (final IOException | JSONException e) {
|
|
||||||
Log.e(TAG, e.getMessage(), e);
|
|
||||||
handleFail(searchString);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
protected final void handleSuccess(final String card, final String user) {
|
|
||||||
runOnUiThread(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
setResult(RESULT_OK, new Intent().putExtra("user", user).putExtra("card", card));
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
protected final void handleFail(final String searchString) {
|
|
||||||
runOnUiThread(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
String message = String.format(getIntent().getStringExtra("identifier_not_found"), searchString)
|
|
||||||
+ ".\n"
|
|
||||||
+ String.format(getIntent().getStringExtra("error_contact_support"), BuildConfig.supportPhone);
|
|
||||||
Toast.makeText(AbstractScannerActivity.this, message, Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
|
||||||
getMenuInflater().inflate(R.menu.menu, menu);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onPrepareOptionsMenu(Menu menu) {
|
|
||||||
|
|
||||||
MenuItem settings = menu.findItem(R.id.settings);
|
|
||||||
settings.setIcon(getResources().getDrawable(R.drawable.settings));
|
|
||||||
settings.setTitle(getIntent().getStringExtra("settings"));
|
|
||||||
|
|
||||||
MenuItem faq = menu.findItem(R.id.faq);
|
|
||||||
faq.setIcon(getResources().getDrawable(R.drawable.help));
|
|
||||||
faq.setTitle(getIntent().getStringExtra("faq"));
|
|
||||||
|
|
||||||
MenuItem exit = menu.findItem(R.id.exit);
|
|
||||||
exit.setIcon(getResources().getDrawable(R.drawable.exit));
|
|
||||||
exit.setTitle(getIntent().getStringExtra("exit"));
|
|
||||||
|
|
||||||
return super.onPrepareOptionsMenu(menu);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
|
||||||
if (item.getItemId() == R.id.settings) {
|
|
||||||
final Intent intent = new Intent();
|
|
||||||
intent.putExtra("item", "settings");
|
|
||||||
setResult(RESULT_OK, intent);
|
|
||||||
finish();
|
|
||||||
return true;
|
|
||||||
} else if (item.getItemId() == R.id.exit) {
|
|
||||||
exit();
|
|
||||||
return true;
|
|
||||||
} else if (item.getItemId() == R.id.faq) {
|
|
||||||
final Intent intent = new Intent();
|
|
||||||
intent.putExtra("item", "faq");
|
|
||||||
setResult(RESULT_OK, intent);
|
|
||||||
finish();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return super.onOptionsItemSelected(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
void exit() {
|
|
||||||
final Intent intent = new Intent();
|
|
||||||
intent.putExtra("item", "exit");
|
|
||||||
setResult(RESULT_OK, intent);
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
package com.dinect.checker;
|
|
||||||
|
|
||||||
public enum SearchType {
|
|
||||||
CARD,
|
|
||||||
PHONE_NUMBER
|
|
||||||
}
|
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
package com.dinect.checker;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.support.annotation.Nullable;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.view.View;
|
|
||||||
import android.widget.ImageButton;
|
|
||||||
import android.widget.LinearLayout;
|
|
||||||
|
|
||||||
import com.dinect.checker.R;
|
|
||||||
import com.dinect.checker.SearchType;
|
|
||||||
|
|
||||||
public class StatedImageButton extends LinearLayout {
|
|
||||||
private Context mContext;
|
|
||||||
private View mRootView;
|
|
||||||
|
|
||||||
private ImageButton mBtnImageState;
|
|
||||||
private SearchType mCurrentButtonState = SearchType.CARD;
|
|
||||||
private StatedImageButtonInteractorListener statedImageButtonInteractorListener;
|
|
||||||
|
|
||||||
public StatedImageButton(Context context) {
|
|
||||||
super(context);
|
|
||||||
init(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public SearchType getCurrentState() {
|
|
||||||
return mCurrentButtonState;
|
|
||||||
}
|
|
||||||
|
|
||||||
public StatedImageButton(Context context, @Nullable AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
init(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public StatedImageButton(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
|
||||||
super(context, attrs, defStyleAttr);
|
|
||||||
init(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void init(Context context) {
|
|
||||||
mContext = context;
|
|
||||||
mRootView = inflate(mContext, R.layout.partial_buttons_layout, this);
|
|
||||||
mBtnImageState = (ImageButton) mRootView.findViewById(R.id.btn_image_state);
|
|
||||||
mBtnImageState.setOnClickListener(new OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
if (mCurrentButtonState == SearchType.CARD) {
|
|
||||||
mCurrentButtonState = SearchType.PHONE_NUMBER;
|
|
||||||
} else {
|
|
||||||
mCurrentButtonState = SearchType.CARD;
|
|
||||||
}
|
|
||||||
setButtonState(mCurrentButtonState);
|
|
||||||
if (statedImageButtonInteractorListener != null) {
|
|
||||||
statedImageButtonInteractorListener.onStateChanged(mCurrentButtonState);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setButtonState(SearchType searchType) {
|
|
||||||
mCurrentButtonState = searchType;
|
|
||||||
|
|
||||||
switch (mCurrentButtonState) {
|
|
||||||
case CARD:
|
|
||||||
mBtnImageState.setBackground(getResources().getDrawable(R.drawable.ic_card));
|
|
||||||
break;
|
|
||||||
case PHONE_NUMBER:
|
|
||||||
mBtnImageState.setBackground(getResources().getDrawable(R.drawable.ic_phone));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStatedImageButtonInteractorListener(StatedImageButtonInteractorListener statedImageButtonInteractorListener) {
|
|
||||||
this.statedImageButtonInteractorListener = statedImageButtonInteractorListener;
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface StatedImageButtonInteractorListener {
|
|
||||||
void onStateChanged(SearchType searchType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
package com.dinect.checker;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.net.ConnectivityManager;
|
|
||||||
import android.net.NetworkInfo;
|
|
||||||
|
|
||||||
public class Utils {
|
|
||||||
|
|
||||||
private Utils() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isOnline(Context context) {
|
|
||||||
NetworkInfo netInfo = getConnectivityManager(context).getActiveNetworkInfo();
|
|
||||||
return netInfo != null && netInfo.isConnected();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static ConnectivityManager getConnectivityManager(Context context) {
|
|
||||||
return (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2017 .
|
|
||||||
*
|
|
||||||
* 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 com.dinect.checker.net;
|
|
||||||
|
|
||||||
import android.support.annotation.NonNull;
|
|
||||||
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import okhttp3.Callback;
|
|
||||||
import okhttp3.HttpUrl;
|
|
||||||
import okhttp3.OkHttpClient;
|
|
||||||
import okhttp3.Request;
|
|
||||||
|
|
||||||
import com.dinect.checker.SearchType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by anonymous
|
|
||||||
*/
|
|
||||||
public final class ApiClient {
|
|
||||||
|
|
||||||
private static final String TAG = "Checker.ApiClient";
|
|
||||||
|
|
||||||
private static final int TIMEOUT = 3;
|
|
||||||
|
|
||||||
private OkHttpClient mHttp;
|
|
||||||
private String mEndpoint;
|
|
||||||
|
|
||||||
public ApiClient(final String url, final @NonNull String appToken, final @NonNull String token) {
|
|
||||||
mEndpoint = url;
|
|
||||||
mHttp = new OkHttpClient().
|
|
||||||
newBuilder()
|
|
||||||
.connectTimeout(TIMEOUT, TimeUnit.SECONDS)
|
|
||||||
.readTimeout(TIMEOUT, TimeUnit.SECONDS)
|
|
||||||
.writeTimeout(TIMEOUT, TimeUnit.SECONDS)
|
|
||||||
.addInterceptor(new DinectAuthorizationInterceptor(appToken, token, "checker/0.1", true))
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void findUser(String searchString, SearchType searchType, Callback callback) {
|
|
||||||
final Request.Builder requestBuilder = new Request.Builder();
|
|
||||||
final HttpUrl url = HttpUrl.parse(mEndpoint);
|
|
||||||
if (url != null) {
|
|
||||||
HttpUrl.Builder httpBuilder = url.newBuilder();
|
|
||||||
switch (searchType) {
|
|
||||||
case CARD:
|
|
||||||
httpBuilder.addQueryParameter("auto", searchString);
|
|
||||||
break;
|
|
||||||
case PHONE_NUMBER:
|
|
||||||
httpBuilder.addQueryParameter("phone", searchString);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
mHttp.newCall(requestBuilder.url(httpBuilder.build()).build()).enqueue(callback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2017 .
|
|
||||||
*
|
|
||||||
* 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 com.dinect.checker.net;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import okhttp3.Headers;
|
|
||||||
import okhttp3.HttpUrl;
|
|
||||||
import okhttp3.Interceptor;
|
|
||||||
import okhttp3.Request;
|
|
||||||
import okhttp3.Response;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author anonymous
|
|
||||||
*/
|
|
||||||
public final class DinectAuthorizationInterceptor implements Interceptor {
|
|
||||||
|
|
||||||
private final String token;
|
|
||||||
private final String appToken;
|
|
||||||
|
|
||||||
private final String dmAuthorization;
|
|
||||||
private final String authorization;
|
|
||||||
private final String userAgent;
|
|
||||||
private final boolean useAuthHeader;
|
|
||||||
|
|
||||||
public DinectAuthorizationInterceptor(final String appToken, final String token, final String clientInfo, final boolean useAuthHeader) {
|
|
||||||
this.appToken = appToken;
|
|
||||||
this.token = token;
|
|
||||||
this.useAuthHeader = useAuthHeader;
|
|
||||||
userAgent = clientInfo;
|
|
||||||
// optimization: concatenate once
|
|
||||||
dmAuthorization = "dmapptoken " + appToken;
|
|
||||||
authorization = "dmtoken " + token;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Response intercept(Interceptor.Chain chain) throws IOException {
|
|
||||||
|
|
||||||
final Request originalRequest = chain.request();
|
|
||||||
final HttpUrl originalUrl = originalRequest.url();
|
|
||||||
final Request.Builder requestBuilder = originalRequest.newBuilder();
|
|
||||||
|
|
||||||
HttpUrl url = originalUrl;
|
|
||||||
Headers headers;
|
|
||||||
|
|
||||||
headers = originalRequest.headers();
|
|
||||||
final Headers.Builder headersBuilder = headers.newBuilder();
|
|
||||||
// always set UA and content type
|
|
||||||
headersBuilder.set("User-Agent", userAgent);
|
|
||||||
|
|
||||||
// Add auth info. Either in headers or query parameters
|
|
||||||
if (useAuthHeader) {
|
|
||||||
headersBuilder.set("DM-Authorization", dmAuthorization);
|
|
||||||
if (null != token) {
|
|
||||||
headersBuilder.set("Authorization", authorization);
|
|
||||||
}
|
|
||||||
headers = headersBuilder.build();
|
|
||||||
} else {
|
|
||||||
final HttpUrl.Builder urlBuilder = originalRequest.url().newBuilder();
|
|
||||||
urlBuilder.addQueryParameter("_dmapptoken", appToken);
|
|
||||||
urlBuilder.addQueryParameter("user_agent", userAgent);
|
|
||||||
if (null != token) {
|
|
||||||
urlBuilder.addQueryParameter("_dmtoken", token);
|
|
||||||
}
|
|
||||||
url = urlBuilder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
final Request request = requestBuilder.url(url).headers(headers).build();
|
|
||||||
return chain.proceed(request);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,179 +0,0 @@
|
|||||||
package com.dinect.checker.zbar;
|
|
||||||
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.hardware.Camera;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.os.Handler;
|
|
||||||
import android.text.TextUtils;
|
|
||||||
import android.view.View;
|
|
||||||
import android.widget.EditText;
|
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import com.dinect.checker.AbstractScannerActivity;
|
|
||||||
import com.dinect.checker.R;
|
|
||||||
import com.dinect.checker.Utils;
|
|
||||||
|
|
||||||
import net.sourceforge.zbar.Config;
|
|
||||||
import net.sourceforge.zbar.Image;
|
|
||||||
import net.sourceforge.zbar.ImageScanner;
|
|
||||||
import net.sourceforge.zbar.Symbol;
|
|
||||||
import net.sourceforge.zbar.SymbolSet;
|
|
||||||
|
|
||||||
public class CameraActivity extends AbstractScannerActivity implements
|
|
||||||
Camera.PreviewCallback {
|
|
||||||
|
|
||||||
public static final String ERROR_INFO = "ERROR_INFO";
|
|
||||||
|
|
||||||
private int mOffset;
|
|
||||||
|
|
||||||
private CameraPreview mPreview;
|
|
||||||
private Camera mCamera;
|
|
||||||
private ImageScanner mScanner;
|
|
||||||
private Handler mAutoFocusHandler;
|
|
||||||
private boolean mPreviewing = true;
|
|
||||||
|
|
||||||
static {
|
|
||||||
System.loadLibrary("iconv");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
|
|
||||||
if (!init(R.layout.a_zbar)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
initToolbar(getIntent());
|
|
||||||
|
|
||||||
mPreview = (CameraPreview) initScanner();
|
|
||||||
|
|
||||||
addScanner(mPreview, R.id.zbarRoot);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected View initScanner() {
|
|
||||||
mOffset = (int) (56 * getResources().getDisplayMetrics().density);
|
|
||||||
|
|
||||||
mAutoFocusHandler = new Handler();
|
|
||||||
|
|
||||||
// create and configure image scanner
|
|
||||||
mScanner = new ImageScanner();
|
|
||||||
mScanner.setConfig(0, Config.X_DENSITY, 3);
|
|
||||||
mScanner.setConfig(0, Config.Y_DENSITY, 3);
|
|
||||||
|
|
||||||
int[] symbols = getIntent().getIntArrayExtra(SCAN_MODES);
|
|
||||||
if (symbols != null) {
|
|
||||||
mScanner.setConfig(Symbol.NONE, Config.ENABLE, 0);
|
|
||||||
for (int symbol : symbols) {
|
|
||||||
mScanner.setConfig(symbol, Config.ENABLE, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mPreview = new CameraPreview(this, this, autoFocusCB);
|
|
||||||
|
|
||||||
return mPreview;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
|
|
||||||
// Open the default i.e. the first rear facing camera.
|
|
||||||
mCamera = Camera.open();
|
|
||||||
if (mCamera == null) {
|
|
||||||
// Cancel request if mCamera is null.
|
|
||||||
cancelRequest();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mPreview.setCamera(mCamera);
|
|
||||||
mPreview.showSurfaceView();
|
|
||||||
|
|
||||||
mPreviewing = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPause() {
|
|
||||||
super.onPause();
|
|
||||||
|
|
||||||
// Because the Camera object is a shared resource, it's very
|
|
||||||
// important to release it when the activity is paused.
|
|
||||||
if (mCamera != null) {
|
|
||||||
mPreview.setCamera(null);
|
|
||||||
mCamera.cancelAutoFocus();
|
|
||||||
mCamera.setPreviewCallback(null);
|
|
||||||
mCamera.stopPreview();
|
|
||||||
mCamera.release();
|
|
||||||
|
|
||||||
// According to Jason Kuang on http://stackoverflow.com/questions/6519120/how-to-recover-camera-preview-from-sleep,
|
|
||||||
// there might be surface recreation problems when the device goes to sleep. So lets just hide it and
|
|
||||||
// recreate on resume
|
|
||||||
mPreview.hideSurfaceView();
|
|
||||||
|
|
||||||
mPreviewing = false;
|
|
||||||
mCamera = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void cancelRequest() {
|
|
||||||
Intent dataIntent = new Intent();
|
|
||||||
dataIntent.putExtra(ERROR_INFO, "Camera unavailable");
|
|
||||||
setResult(RESULT_CANCELED, dataIntent);
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onPreviewFrame(byte[] data, Camera camera) {
|
|
||||||
if (mPreviewing) {
|
|
||||||
Camera.Parameters parameters = camera.getParameters();
|
|
||||||
Camera.Size size = parameters.getPreviewSize();
|
|
||||||
|
|
||||||
Image barcode = new Image(size.width, size.height, "Y800");
|
|
||||||
barcode.setData(data);
|
|
||||||
barcode.setCrop((size.width / 2) - mOffset, 0, (size.width / 2) + mOffset, size.height);
|
|
||||||
|
|
||||||
int result = mScanner.scanImage(barcode);
|
|
||||||
|
|
||||||
if (result != 0) {
|
|
||||||
mPreviewing = false;
|
|
||||||
SymbolSet syms = mScanner.getResults();
|
|
||||||
for (Symbol sym : syms) {
|
|
||||||
String symData = sym.getData();
|
|
||||||
if (!TextUtils.isEmpty(symData) && Utils.isOnline(this)) {
|
|
||||||
requestUser(sym.getData());
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
mPreviewing = true;
|
|
||||||
Toast.makeText(this, "Проверьте интернет соединение", Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Runnable doAutoFocus = new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
if (mCamera != null && mPreviewing) {
|
|
||||||
mCamera.autoFocus(autoFocusCB);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Mimic continuous auto-focusing
|
|
||||||
Camera.AutoFocusCallback autoFocusCB = new Camera.AutoFocusCallback() {
|
|
||||||
public void onAutoFocus(boolean success, Camera camera) {
|
|
||||||
mAutoFocusHandler.postDelayed(doAutoFocus, 1000);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBackPressed() {
|
|
||||||
setResult(RESULT_CANCELED);
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void requestUser(String code) {
|
|
||||||
handleBarcode(code);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,209 +0,0 @@
|
|||||||
package com.dinect.checker.zbar;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.hardware.Camera;
|
|
||||||
import android.hardware.Camera.AutoFocusCallback;
|
|
||||||
import android.hardware.Camera.CameraInfo;
|
|
||||||
import android.hardware.Camera.PreviewCallback;
|
|
||||||
import android.hardware.Camera.Size;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.Surface;
|
|
||||||
import android.view.SurfaceHolder;
|
|
||||||
import android.view.SurfaceView;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
class CameraPreview extends ViewGroup implements SurfaceHolder.Callback {
|
|
||||||
|
|
||||||
private final static String TAG = "Checker.CameraPreview";
|
|
||||||
|
|
||||||
SurfaceView mSurfaceView;
|
|
||||||
SurfaceHolder mHolder;
|
|
||||||
Size mPreviewSize;
|
|
||||||
List<Size> mSupportedPreviewSizes;
|
|
||||||
Camera mCamera;
|
|
||||||
PreviewCallback mPreviewCallback;
|
|
||||||
AutoFocusCallback mAutoFocusCallback;
|
|
||||||
|
|
||||||
CameraPreview(Context context, PreviewCallback previewCallback, AutoFocusCallback autoFocusCb) {
|
|
||||||
super(context);
|
|
||||||
|
|
||||||
mPreviewCallback = previewCallback;
|
|
||||||
mAutoFocusCallback = autoFocusCb;
|
|
||||||
mSurfaceView = new SurfaceView(context);
|
|
||||||
addView(mSurfaceView);
|
|
||||||
|
|
||||||
// Install a SurfaceHolder.Callback so we get notified when the
|
|
||||||
// underlying surface is created and destroyed.
|
|
||||||
mHolder = mSurfaceView.getHolder();
|
|
||||||
mHolder.addCallback(this);
|
|
||||||
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCamera(Camera camera) {
|
|
||||||
mCamera = camera;
|
|
||||||
if (mCamera != null) {
|
|
||||||
mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();
|
|
||||||
requestLayout();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
|
||||||
// We purposely disregard child measurements because act as a
|
|
||||||
// wrapper to a SurfaceView that centers the camera preview instead
|
|
||||||
// of stretching it.
|
|
||||||
final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
|
|
||||||
final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);
|
|
||||||
setMeasuredDimension(width, height);
|
|
||||||
|
|
||||||
if (mSupportedPreviewSizes != null) {
|
|
||||||
mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
|
||||||
if (changed && getChildCount() > 0) {
|
|
||||||
final View child = getChildAt(0);
|
|
||||||
|
|
||||||
final int width = r - l;
|
|
||||||
final int height = b - t;
|
|
||||||
|
|
||||||
int previewWidth = width;
|
|
||||||
int previewHeight = height;
|
|
||||||
if (mPreviewSize != null) {
|
|
||||||
previewWidth = mPreviewSize.width;
|
|
||||||
previewHeight = mPreviewSize.height;
|
|
||||||
}
|
|
||||||
|
|
||||||
child.layout(0, 0, width, height);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void hideSurfaceView() {
|
|
||||||
mSurfaceView.setVisibility(View.INVISIBLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void showSurfaceView() {
|
|
||||||
mSurfaceView.setVisibility(View.VISIBLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void surfaceCreated(SurfaceHolder holder) {
|
|
||||||
// The Surface has been created, acquire the camera and tell it where
|
|
||||||
// to draw.
|
|
||||||
try {
|
|
||||||
if (mCamera != null) {
|
|
||||||
mCamera.setPreviewDisplay(holder);
|
|
||||||
}
|
|
||||||
} catch (IOException exception) {
|
|
||||||
Log.e(TAG, "IOException caused by setPreviewDisplay()", exception);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void surfaceDestroyed(SurfaceHolder holder) {
|
|
||||||
// Surface will be destroyed when we return, so stop the preview.
|
|
||||||
if (mCamera != null) {
|
|
||||||
mCamera.cancelAutoFocus();
|
|
||||||
mCamera.stopPreview();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
|
|
||||||
final double ASPECT_TOLERANCE = 0.1;
|
|
||||||
double targetRatio = (double) w / h;
|
|
||||||
if (sizes == null) return null;
|
|
||||||
|
|
||||||
Size optimalSize = null;
|
|
||||||
double minDiff = Double.MAX_VALUE;
|
|
||||||
|
|
||||||
int targetHeight = h;
|
|
||||||
|
|
||||||
// Try to find an size match aspect ratio and size
|
|
||||||
for (Size size : sizes) {
|
|
||||||
double ratio = (double) size.width / size.height;
|
|
||||||
if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
|
|
||||||
if (Math.abs(size.height - targetHeight) < minDiff) {
|
|
||||||
optimalSize = size;
|
|
||||||
minDiff = Math.abs(size.height - targetHeight);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cannot find the one match the aspect ratio, ignore the requirement
|
|
||||||
if (optimalSize == null) {
|
|
||||||
minDiff = Double.MAX_VALUE;
|
|
||||||
for (Size size : sizes) {
|
|
||||||
if (Math.abs(size.height - targetHeight) < minDiff) {
|
|
||||||
optimalSize = size;
|
|
||||||
minDiff = Math.abs(size.height - targetHeight);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return optimalSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
|
|
||||||
if (holder.getSurface() == null) {
|
|
||||||
// preview surface does not exist
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mCamera != null) {
|
|
||||||
// Now that the size is known, set up the camera parameters and begin
|
|
||||||
// the preview.
|
|
||||||
setCameraDisplayOrientation(0);
|
|
||||||
Camera.Parameters parameters = mCamera.getParameters();
|
|
||||||
parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
|
|
||||||
requestLayout();
|
|
||||||
|
|
||||||
mCamera.setParameters(parameters);
|
|
||||||
mCamera.setPreviewCallback(mPreviewCallback);
|
|
||||||
mCamera.startPreview();
|
|
||||||
mCamera.autoFocus(mAutoFocusCallback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void setCameraDisplayOrientation(int cameraId) {
|
|
||||||
|
|
||||||
int rotation = ((Activity) getContext()).getWindowManager().getDefaultDisplay().getRotation();
|
|
||||||
int degrees = 0;
|
|
||||||
switch (rotation) {
|
|
||||||
case Surface.ROTATION_0:
|
|
||||||
degrees = 0;
|
|
||||||
break;
|
|
||||||
case Surface.ROTATION_90:
|
|
||||||
degrees = 90;
|
|
||||||
break;
|
|
||||||
case Surface.ROTATION_180:
|
|
||||||
degrees = 180;
|
|
||||||
break;
|
|
||||||
case Surface.ROTATION_270:
|
|
||||||
degrees = 270;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
int result = 0;
|
|
||||||
|
|
||||||
// получаем инфо по камере cameraId
|
|
||||||
CameraInfo info = new CameraInfo();
|
|
||||||
Camera.getCameraInfo(cameraId, info);
|
|
||||||
|
|
||||||
// задняя камера
|
|
||||||
if (info.facing == CameraInfo.CAMERA_FACING_BACK) {
|
|
||||||
result = ((360 - degrees) + info.orientation);
|
|
||||||
} else
|
|
||||||
// передняя камера
|
|
||||||
if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {
|
|
||||||
result = ((360 - degrees) - info.orientation);
|
|
||||||
result += 360;
|
|
||||||
}
|
|
||||||
result = result % 360;
|
|
||||||
mCamera.setDisplayOrientation(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2017 .
|
|
||||||
*
|
|
||||||
* 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 com.dinect.checker.zxing;
|
|
||||||
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.os.Handler;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.View;
|
|
||||||
import android.widget.EditText;
|
|
||||||
|
|
||||||
import com.dinect.checker.AbstractScannerActivity;
|
|
||||||
import com.dinect.checker.R;
|
|
||||||
import com.google.zxing.BarcodeFormat;
|
|
||||||
import com.google.zxing.Result;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
import me.dm7.barcodescanner.zxing.ZXingScannerView;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by anonymous
|
|
||||||
*/
|
|
||||||
public class ScannerActivity extends AbstractScannerActivity
|
|
||||||
implements ZXingScannerView.ResultHandler {
|
|
||||||
|
|
||||||
private static final int SCAN_INTERVAL_PERIOD = 500;
|
|
||||||
|
|
||||||
private ZXingScannerView scannerView;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(Bundle state) {
|
|
||||||
super.onCreate(state);
|
|
||||||
|
|
||||||
if (!init(R.layout.a_zxing)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
initToolbar(getIntent());
|
|
||||||
|
|
||||||
scannerView = (ZXingScannerView) initScanner();
|
|
||||||
addScanner(scannerView, R.id.zxingRoot);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected View initScanner() {
|
|
||||||
return new ZXingScannerView(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
scannerView.setResultHandler(this);
|
|
||||||
scannerView.startCamera();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPause() {
|
|
||||||
super.onPause();
|
|
||||||
scannerView.stopCamera();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBackPressed() {
|
|
||||||
setResult(RESULT_CANCELED);
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleResult(Result raw) {
|
|
||||||
handleBarcode(raw.getText());
|
|
||||||
scannerView.postDelayed(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
scannerView.resumeCameraPreview(ScannerActivity.this);
|
|
||||||
}
|
|
||||||
}, SCAN_INTERVAL_PERIOD);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
android:id="@+id/zbarRoot"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:background="@android:color/white">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<View
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
android:layout_marginBottom="56dp"
|
|
||||||
android:layout_weight="0.5"/>
|
|
||||||
|
|
||||||
<View
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
android:layout_marginTop="56dp"
|
|
||||||
android:layout_weight="0.5" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<View
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="1dp"
|
|
||||||
android:layout_gravity="center"
|
|
||||||
android:layout_marginBottom="56dp"
|
|
||||||
android:background="#00ff00" />
|
|
||||||
|
|
||||||
<View
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="1dp"
|
|
||||||
android:layout_gravity="center"
|
|
||||||
android:layout_marginTop="56dp"
|
|
||||||
android:background="#00ff00" />
|
|
||||||
|
|
||||||
<include layout="@layout/v_custom_toolbar" />
|
|
||||||
|
|
||||||
<View
|
|
||||||
android:id="@+id/toolbarShadow"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="4dp"
|
|
||||||
android:layout_marginTop="?attr/actionBarSize"
|
|
||||||
android:background="@drawable/shadow_bottom" />
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<merge xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<ImageButton
|
|
||||||
android:id="@+id/btn_image_state"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
/>
|
|
||||||
</LinearLayout>
|
|
||||||
</merge>
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
<resources>
|
|
||||||
<dimen name="scanner_contour_left">24dp</dimen>
|
|
||||||
<dimen name="scanner_contour_top">178dp</dimen>
|
|
||||||
<dimen name="scanner_contour_height">232dp</dimen>
|
|
||||||
</resources>
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
<resources>
|
|
||||||
|
|
||||||
<!-- Base application theme. -->
|
|
||||||
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
|
|
||||||
<item name="android:textColorSecondary">@android:color/white</item>
|
|
||||||
</style>
|
|
||||||
|
|
||||||
</resources>
|
|
||||||
Binary file not shown.
Binary file not shown.
@@ -80,6 +80,56 @@ FLUTTER_EXPORT
|
|||||||
@interface FlutterJSONMessageCodec : NSObject <FlutterMessageCodec>
|
@interface FlutterJSONMessageCodec : NSObject <FlutterMessageCodec>
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
/**
|
||||||
|
A writer of the Flutter standard binary encoding.
|
||||||
|
|
||||||
|
See `FlutterStandardMessageCodec` for details on the encoding.
|
||||||
|
|
||||||
|
The encoding is extensible via subclasses overriding `writeValue`.
|
||||||
|
*/
|
||||||
|
FLUTTER_EXPORT
|
||||||
|
@interface FlutterStandardWriter : NSObject
|
||||||
|
- (instancetype)initWithData:(NSMutableData*)data;
|
||||||
|
- (void)writeByte:(UInt8)value;
|
||||||
|
- (void)writeBytes:(const void*)bytes length:(NSUInteger)length;
|
||||||
|
- (void)writeData:(NSData*)data;
|
||||||
|
- (void)writeSize:(UInt32)size;
|
||||||
|
- (void)writeAlignment:(UInt8)alignment;
|
||||||
|
- (void)writeUTF8:(NSString*)value;
|
||||||
|
- (void)writeValue:(id)value;
|
||||||
|
@end
|
||||||
|
|
||||||
|
/**
|
||||||
|
A reader of the Flutter standard binary encoding.
|
||||||
|
|
||||||
|
See `FlutterStandardMessageCodec` for details on the encoding.
|
||||||
|
|
||||||
|
The encoding is extensible via subclasses overriding `readValueOfType`.
|
||||||
|
*/
|
||||||
|
FLUTTER_EXPORT
|
||||||
|
@interface FlutterStandardReader : NSObject
|
||||||
|
- (instancetype)initWithData:(NSData*)data;
|
||||||
|
- (BOOL)hasMore;
|
||||||
|
- (UInt8)readByte;
|
||||||
|
- (void)readBytes:(void*)destination length:(NSUInteger)length;
|
||||||
|
- (NSData*)readData:(NSUInteger)length;
|
||||||
|
- (UInt32)readSize;
|
||||||
|
- (void)readAlignment:(UInt8)alignment;
|
||||||
|
- (NSString*)readUTF8;
|
||||||
|
- (id)readValue;
|
||||||
|
- (id)readValueOfType:(UInt8)type;
|
||||||
|
@end
|
||||||
|
|
||||||
|
/**
|
||||||
|
A factory of compatible reader/writer instances using the Flutter standard
|
||||||
|
binary encoding or extensions thereof.
|
||||||
|
*/
|
||||||
|
FLUTTER_EXPORT
|
||||||
|
@interface FlutterStandardReaderWriter : NSObject
|
||||||
|
- (FlutterStandardWriter*)writerWithData:(NSMutableData*)data;
|
||||||
|
- (FlutterStandardReader*)readerWithData:(NSData*)data;
|
||||||
|
@end
|
||||||
|
|
||||||
/**
|
/**
|
||||||
A `FlutterMessageCodec` using the Flutter standard binary encoding.
|
A `FlutterMessageCodec` using the Flutter standard binary encoding.
|
||||||
|
|
||||||
@@ -114,6 +164,7 @@ FLUTTER_EXPORT
|
|||||||
*/
|
*/
|
||||||
FLUTTER_EXPORT
|
FLUTTER_EXPORT
|
||||||
@interface FlutterStandardMessageCodec : NSObject <FlutterMessageCodec>
|
@interface FlutterStandardMessageCodec : NSObject <FlutterMessageCodec>
|
||||||
|
+ (instancetype)codecWithReaderWriter:(FlutterStandardReaderWriter*)readerWriter;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -374,6 +425,7 @@ FLUTTER_EXPORT
|
|||||||
*/
|
*/
|
||||||
FLUTTER_EXPORT
|
FLUTTER_EXPORT
|
||||||
@interface FlutterStandardMethodCodec : NSObject <FlutterMethodCodec>
|
@interface FlutterStandardMethodCodec : NSObject <FlutterMethodCodec>
|
||||||
|
+ (instancetype)codecWithReaderWriter:(FlutterStandardReaderWriter*)readerWriter;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
NS_ASSUME_NONNULL_END
|
||||||
|
|||||||
@@ -23,6 +23,26 @@ FLUTTER_EXPORT
|
|||||||
|
|
||||||
- (instancetype)initFromDefaultSourceForConfiguration;
|
- (instancetype)initFromDefaultSourceForConfiguration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns the file name for the given asset.
|
||||||
|
The returned file name can be used to access the asset in the application's main bundle.
|
||||||
|
|
||||||
|
- Parameter asset: The name of the asset. The name can be hierarchical.
|
||||||
|
- Returns: the file name to be used for lookup in the main bundle.
|
||||||
|
*/
|
||||||
|
+ (NSString*)lookupKeyForAsset:(NSString*)asset;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns the file name for the given asset which originates from the specified package.
|
||||||
|
The returned file name can be used to access the asset in the application's main bundle.
|
||||||
|
|
||||||
|
- Parameters:
|
||||||
|
- asset: The name of the asset. The name can be hierarchical.
|
||||||
|
- package: The name of the package from which the asset originates.
|
||||||
|
- Returns: the file name to be used for lookup in the main bundle.
|
||||||
|
*/
|
||||||
|
+ (NSString*)lookupKeyForAsset:(NSString*)asset fromPackage:(NSString*)package;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
#endif // FLUTTER_FLUTTERDARTPROJECT_H_
|
#endif // FLUTTER_FLUTTERDARTPROJECT_H_
|
||||||
|
|||||||
@@ -183,6 +183,26 @@ NS_ASSUME_NONNULL_BEGIN
|
|||||||
- Parameters delegate: The receiving object, such as the plugin's main class.
|
- Parameters delegate: The receiving object, such as the plugin's main class.
|
||||||
*/
|
*/
|
||||||
- (void)addApplicationDelegate:(NSObject<FlutterPlugin>*)delegate;
|
- (void)addApplicationDelegate:(NSObject<FlutterPlugin>*)delegate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns the file name for the given asset.
|
||||||
|
The returned file name can be used to access the asset in the application's main bundle.
|
||||||
|
|
||||||
|
- Parameter asset: The name of the asset. The name can be hierarchical.
|
||||||
|
- Returns: the file name to be used for lookup in the main bundle.
|
||||||
|
*/
|
||||||
|
- (NSString*)lookupKeyForAsset:(NSString*)asset;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns the file name for the given asset which originates from the specified package.
|
||||||
|
The returned file name can be used to access the asset in the application's main bundle.
|
||||||
|
|
||||||
|
- Parameters:
|
||||||
|
- asset: The name of the asset. The name can be hierarchical.
|
||||||
|
- package: The name of the package from which the asset originates.
|
||||||
|
- Returns: the file name to be used for lookup in the main bundle.
|
||||||
|
*/
|
||||||
|
- (NSString*)lookupKeyForAsset:(NSString*)asset fromPackage:(NSString*)package;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||||||
|
|
||||||
FLUTTER_EXPORT
|
FLUTTER_EXPORT
|
||||||
@protocol FlutterTexture<NSObject>
|
@protocol FlutterTexture<NSObject>
|
||||||
- (CVPixelBufferRef)copyPixelBuffer;
|
- (CVPixelBufferRef _Nullable)copyPixelBuffer;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
FLUTTER_EXPORT
|
FLUTTER_EXPORT
|
||||||
|
|||||||
@@ -22,6 +22,26 @@ FLUTTER_EXPORT
|
|||||||
|
|
||||||
- (void)handleStatusBarTouches:(UIEvent*)event;
|
- (void)handleStatusBarTouches:(UIEvent*)event;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns the file name for the given asset.
|
||||||
|
The returned file name can be used to access the asset in the application's main bundle.
|
||||||
|
|
||||||
|
- Parameter asset: The name of the asset. The name can be hierarchical.
|
||||||
|
- Returns: the file name to be used for lookup in the main bundle.
|
||||||
|
*/
|
||||||
|
- (NSString*)lookupKeyForAsset:(NSString*)asset;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns the file name for the given asset which originates from the specified package.
|
||||||
|
The returned file name can be used to access the asset in the application's main bundle.
|
||||||
|
|
||||||
|
- Parameters:
|
||||||
|
- asset: The name of the asset. The name can be hierarchical.
|
||||||
|
- package: The name of the package from which the asset originates.
|
||||||
|
- Returns: the file name to be used for lookup in the main bundle.
|
||||||
|
*/
|
||||||
|
- (NSString*)lookupKeyForAsset:(NSString*)asset fromPackage:(NSString*)package;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Sets the first route that the Flutter app shows. The default is "/".
|
Sets the first route that the Flutter app shows. The default is "/".
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
// This is a generated file; do not edit or check into version control.
|
// This is a generated file; do not edit or check into version control.
|
||||||
FLUTTER_ROOT=/Users/dinect/projects/flutter
|
FLUTTER_ROOT=/Users/kifio/flutter
|
||||||
FLUTTER_APPLICATION_PATH=/Users/dinect/projects/checker
|
FLUTTER_APPLICATION_PATH=/Users/kifio/Desktop/AndroidStudioProjects/checker
|
||||||
FLUTTER_TARGET=lib/main.dart
|
FLUTTER_TARGET=lib/main.dart
|
||||||
FLUTTER_BUILD_MODE=release
|
FLUTTER_BUILD_MODE=debug
|
||||||
FLUTTER_BUILD_DIR=build
|
FLUTTER_BUILD_DIR=build
|
||||||
SYMROOT=${SOURCE_ROOT}/../build/ios
|
SYMROOT=${SOURCE_ROOT}/../build/ios
|
||||||
FLUTTER_FRAMEWORK_DIR=/Users/dinect/projects/flutter/bin/cache/artifacts/engine/ios-release
|
FLUTTER_FRAMEWORK_DIR=/Users/kifio/flutter/bin/cache/artifacts/engine/ios
|
||||||
|
PREVIEW_DART_2=true
|
||||||
|
|||||||
@@ -1377,7 +1377,7 @@
|
|||||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
DEFINES_MODULE = YES;
|
DEFINES_MODULE = YES;
|
||||||
DEVELOPMENT_TEAM = 926V94K5Q8;
|
DEVELOPMENT_TEAM = "";
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
@@ -1414,7 +1414,7 @@
|
|||||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
DEFINES_MODULE = YES;
|
DEFINES_MODULE = YES;
|
||||||
DEVELOPMENT_TEAM = 926V94K5Q8;
|
DEVELOPMENT_TEAM = "";
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
|
|||||||
@@ -4,6 +4,11 @@
|
|||||||
<dict>
|
<dict>
|
||||||
<key>SchemeUserState</key>
|
<key>SchemeUserState</key>
|
||||||
<dict>
|
<dict>
|
||||||
|
<key>BioChecker.xcscheme</key>
|
||||||
|
<dict>
|
||||||
|
<key>orderHint</key>
|
||||||
|
<integer>13</integer>
|
||||||
|
</dict>
|
||||||
<key>Dinect INT.xcscheme_^#shared#^_</key>
|
<key>Dinect INT.xcscheme_^#shared#^_</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>orderHint</key>
|
<key>orderHint</key>
|
||||||
@@ -12,13 +17,18 @@
|
|||||||
<key>Dinect-Crypto.xcscheme_^#shared#^_</key>
|
<key>Dinect-Crypto.xcscheme_^#shared#^_</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>orderHint</key>
|
<key>orderHint</key>
|
||||||
<integer>7</integer>
|
<integer>2</integer>
|
||||||
</dict>
|
</dict>
|
||||||
<key>Dinect.xcscheme</key>
|
<key>Dinect.xcscheme</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>orderHint</key>
|
<key>orderHint</key>
|
||||||
<integer>11</integer>
|
<integer>11</integer>
|
||||||
</dict>
|
</dict>
|
||||||
|
<key>Dinect.xcscheme_^#shared#^_</key>
|
||||||
|
<dict>
|
||||||
|
<key>orderHint</key>
|
||||||
|
<integer>3</integer>
|
||||||
|
</dict>
|
||||||
<key>Runner.xcscheme_^#shared#^_</key>
|
<key>Runner.xcscheme_^#shared#^_</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>orderHint</key>
|
<key>orderHint</key>
|
||||||
|
|||||||
Binary file not shown.
@@ -1,5 +1,7 @@
|
|||||||
import UIKit
|
import UIKit
|
||||||
import Flutter
|
import Flutter
|
||||||
|
import DropDown
|
||||||
|
import ZXingObjC
|
||||||
|
|
||||||
@objc class ScannerViewController: UIViewController, ZXCaptureDelegate, UITextFieldDelegate {
|
@objc class ScannerViewController: UIViewController, ZXCaptureDelegate, UITextFieldDelegate {
|
||||||
|
|
||||||
@@ -28,28 +30,18 @@ import Flutter
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// @IBOutlet weak var decodedLabel: UILabel!
|
var captureSizeTransform: CGAffineTransform?
|
||||||
|
|
||||||
private var captureSizeTransform: CGAffineTransform?
|
|
||||||
|
|
||||||
var buttonState: ButtonState = .card
|
var buttonState: ButtonState = .card
|
||||||
|
|
||||||
var platformChannel: FlutterMethodChannel?
|
var platformChannel: FlutterMethodChannel?
|
||||||
|
|
||||||
// Квадрат для наведения на цель (надеюсь)
|
|
||||||
let scanRectView = UIView()
|
|
||||||
|
|
||||||
//Вьюшка для верхнего меню
|
|
||||||
let topView = UIView()
|
|
||||||
|
|
||||||
//Окно ввода кода
|
|
||||||
let textField = UITextField()
|
|
||||||
|
|
||||||
//Кнопка настроек
|
|
||||||
var settingButton: UIButton!
|
|
||||||
|
|
||||||
var strings = [String:String]()
|
var strings = [String:String]()
|
||||||
|
|
||||||
|
let scanRectView = UIView()
|
||||||
|
let header = UIView()
|
||||||
|
let textField = UITextField()
|
||||||
|
let settingsButton = UIButton(type: .system)
|
||||||
|
let searchType = UIButton(type: .system)
|
||||||
|
let dropDown = DropDown()
|
||||||
|
|
||||||
required init?(coder aDecoder: NSCoder) {
|
required init?(coder aDecoder: NSCoder) {
|
||||||
super.init(coder: aDecoder)
|
super.init(coder: aDecoder)
|
||||||
}
|
}
|
||||||
@@ -84,43 +76,59 @@ import Flutter
|
|||||||
|
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
capture.camera = capture.back()
|
|
||||||
capture.focusMode = .continuousAutoFocus
|
|
||||||
view.layer.addSublayer((capture.layer)!)
|
view.layer.addSublayer((capture.layer)!)
|
||||||
view.addSubview(scanRectView)
|
view.addSubview(scanRectView)
|
||||||
|
view.addSubview(header)
|
||||||
|
view.bringSubview(toFront: header)
|
||||||
|
view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(ScannerViewController.hideKeyboard)))
|
||||||
|
|
||||||
settingButton = UIButton(type: .system)
|
initCamera()
|
||||||
settingButton.addTarget(self, action: #selector(ScannerViewController.buttonTouch), for: .touchUpInside)
|
initSearchTypeButton()
|
||||||
|
initTextFIeld()
|
||||||
|
initSettingsButton()
|
||||||
|
initDropDown()
|
||||||
|
initHeader()
|
||||||
|
}
|
||||||
|
|
||||||
topView.addSubview(textField)
|
private func initCamera() {
|
||||||
topView.addSubview(settingButton)
|
capture.camera = capture.back()
|
||||||
view.addSubview(topView)
|
capture.focusMode = .continuousAutoFocus
|
||||||
view.bringSubview(toFront: topView)
|
}
|
||||||
|
|
||||||
|
private func initHeader() {
|
||||||
|
header.addSubview(textField)
|
||||||
|
header.addSubview(searchType)
|
||||||
|
header.addSubview(settingsButton)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func initTextFIeld() {
|
||||||
textField.delegate = self
|
textField.delegate = self
|
||||||
|
|
||||||
let tap = UITapGestureRecognizer(target: self, action: #selector(ScannerViewController.hideKeyboard))
|
|
||||||
view.addGestureRecognizer(tap)
|
|
||||||
|
|
||||||
settingButton.setImage(self.buttonState.icon, for: .normal)
|
|
||||||
textField.placeholder = self.getInputHint()
|
textField.placeholder = self.getInputHint()
|
||||||
// textField.text = "79087654321"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override func viewWillAppear(_ animated: Bool) {
|
private func initSearchTypeButton() {
|
||||||
super.viewWillAppear(animated)
|
searchType.setImage(self.buttonState.icon, for: .normal)
|
||||||
topView.backgroundColor = UIColor.white
|
searchType.addTarget(self, action: #selector(ScannerViewController.buttonTouch), for: .touchUpInside)
|
||||||
textField.borderStyle = .roundedRect
|
|
||||||
capture.delegate = self
|
|
||||||
applyOrientation()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override func viewWillLayoutSubviews() {
|
private func initDropDown() {
|
||||||
scanRectView.frame = view.bounds
|
dropDown.anchorView = settingsButton
|
||||||
topView.frame = CGRect(x: 0, y: 0, width: view.frame.size.width, height: 56)
|
dropDown.dataSource = [strings["settings"]!, strings["faq"]!]
|
||||||
settingButton.frame = CGRect(x: 8, y: 26, width: 20, height: 20)
|
dropDown.selectionAction = { (index: Int, item: String) in
|
||||||
textField.frame = CGRect(x: settingButton.frame.maxX + 8, y: 21,
|
if index == 0 {
|
||||||
width: view.frame.size.width - settingButton.frame.maxX - 16, height: 30)
|
self.platformChannel?.invokeMethod("settings", arguments: nil)
|
||||||
|
} else if index == 1 {
|
||||||
|
self.platformChannel?.invokeMethod("faq", arguments: nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
self.dismiss(animated: false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func initSettingsButton() {
|
||||||
|
settingsButton.setImage(UIImage(named: "more")!, for: .normal)
|
||||||
|
settingsButton.addTarget(self, action: #selector(ScannerViewController.settingsTouch), for: .touchUpInside)
|
||||||
}
|
}
|
||||||
|
|
||||||
func hideKeyboard() {
|
func hideKeyboard() {
|
||||||
@@ -129,12 +137,129 @@ import Flutter
|
|||||||
|
|
||||||
func buttonTouch() {
|
func buttonTouch() {
|
||||||
setButtonState()
|
setButtonState()
|
||||||
settingButton.setImage(self.buttonState.icon, for: .normal)
|
searchType.setImage(self.buttonState.icon, for: .normal)
|
||||||
textField.placeholder = self.getInputHint()
|
textField.placeholder = self.getInputHint()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func settingsTouch() {
|
||||||
|
dropDown.show()
|
||||||
|
}
|
||||||
|
|
||||||
|
override func viewWillAppear(_ animated: Bool) {
|
||||||
|
super.viewWillAppear(animated)
|
||||||
|
header.backgroundColor = UIColor.white
|
||||||
|
textField.borderStyle = .roundedRect
|
||||||
|
capture.delegate = self
|
||||||
|
applyOrientation()
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Вынести эту копипасту в методы, когда будет время
|
||||||
|
override func viewWillLayoutSubviews() {
|
||||||
|
|
||||||
|
// TODO: Надо бы уйти от констант, переписать на отступы какие-нибудь
|
||||||
|
scanRectView.frame = view.bounds
|
||||||
|
header.frame = CGRect(x: 0, y: 0, width: view.frame.size.width, height: 56)
|
||||||
|
searchType.frame = CGRect(x: 8, y: 26, width: 20, height: 20)
|
||||||
|
textField.frame = CGRect(x: searchType.frame.maxX + 8, y: 21, width: view.frame.size.width - searchType.frame.maxX - 48, height: 30)
|
||||||
|
settingsButton.frame = CGRect(x: view.frame.size.width - 30, y: 26, width: 20, height: 20)
|
||||||
|
|
||||||
|
var path = UIBezierPath()
|
||||||
|
path.move(to: CGPoint(x: 32, y: view.frame.size.height / 2))
|
||||||
|
path.addLine(to: CGPoint(x: view.frame.size.width - 32, y: view.frame.size.height / 2))
|
||||||
|
|
||||||
|
var shapeLayer = CAShapeLayer()
|
||||||
|
shapeLayer.path = path.cgPath
|
||||||
|
shapeLayer.strokeColor = UIColor.red.cgColor
|
||||||
|
shapeLayer.fillColor = UIColor.clear.cgColor
|
||||||
|
shapeLayer.lineWidth = 2
|
||||||
|
|
||||||
|
view.layer.addSublayer(shapeLayer)
|
||||||
|
|
||||||
|
path = UIBezierPath()
|
||||||
|
path.move(to: CGPoint(x: 32, y: (view.frame.size.height / 2) - 32))
|
||||||
|
path.addLine(to: CGPoint(x: 32, y: (view.frame.size.height / 2) - 64))
|
||||||
|
path.addLine(to: CGPoint(x: 64, y: (view.frame.size.height / 2) - 64))
|
||||||
|
|
||||||
|
path.move(to: CGPoint(x: view.frame.size.width - 64, y: (view.frame.size.height / 2) - 64))
|
||||||
|
path.addLine(to: CGPoint(x: view.frame.size.width - 32, y: (view.frame.size.height / 2) - 64))
|
||||||
|
path.addLine(to: CGPoint(x: view.frame.size.width - 32, y: (view.frame.size.height / 2) - 32))
|
||||||
|
|
||||||
|
path.move(to: CGPoint(x: 32, y: (view.frame.size.height / 2) + 32))
|
||||||
|
path.addLine(to: CGPoint(x: 32, y: (view.frame.size.height / 2) + 64))
|
||||||
|
path.addLine(to: CGPoint(x: 64, y: (view.frame.size.height / 2) + 64))
|
||||||
|
|
||||||
|
path.move(to: CGPoint(x: view.frame.size.width - 32, y: (view.frame.size.height / 2) + 32))
|
||||||
|
path.addLine(to: CGPoint(x: view.frame.size.width - 32, y: (view.frame.size.height / 2) + 64))
|
||||||
|
path.addLine(to: CGPoint(x: view.frame.size.width - 64, y: (view.frame.size.height / 2) + 64))
|
||||||
|
|
||||||
|
shapeLayer = CAShapeLayer()
|
||||||
|
shapeLayer.path = path.cgPath
|
||||||
|
shapeLayer.strokeColor = UIColor.green.cgColor
|
||||||
|
shapeLayer.fillColor = UIColor.clear.cgColor
|
||||||
|
shapeLayer.lineWidth = 2
|
||||||
|
|
||||||
|
view.layer.addSublayer(shapeLayer)
|
||||||
|
|
||||||
|
path = UIBezierPath()
|
||||||
|
path.move(to: CGPoint(x: 0, y: 56))
|
||||||
|
path.addLine(to: CGPoint(x: view.frame.size.width, y: 56))
|
||||||
|
path.addLine(to: CGPoint(x: view.frame.size.width, y: (view.frame.size.height / 2) - 64))
|
||||||
|
path.addLine(to: CGPoint(x: 0, y: (view.frame.size.height / 2) - 64))
|
||||||
|
path.addLine(to: CGPoint(x: 0, y: 56))
|
||||||
|
path.close()
|
||||||
|
|
||||||
|
shapeLayer = CAShapeLayer()
|
||||||
|
shapeLayer.path = path.cgPath
|
||||||
|
shapeLayer.fillColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.5).cgColor
|
||||||
|
|
||||||
|
view.layer.addSublayer(shapeLayer)
|
||||||
|
|
||||||
|
path = UIBezierPath()
|
||||||
|
path.move(to: CGPoint(x: 0, y: (view.frame.size.height / 2) - 64))
|
||||||
|
path.addLine(to: CGPoint(x: 32, y: (view.frame.size.height / 2) - 64))
|
||||||
|
path.addLine(to: CGPoint(x: 32, y: (view.frame.size.height / 2) + 64))
|
||||||
|
path.addLine(to: CGPoint(x: 0, y: (view.frame.size.height / 2) + 64))
|
||||||
|
path.addLine(to: CGPoint(x: 0, y: (view.frame.size.height / 2) - 64))
|
||||||
|
path.close()
|
||||||
|
|
||||||
|
shapeLayer = CAShapeLayer()
|
||||||
|
shapeLayer.path = path.cgPath
|
||||||
|
shapeLayer.fillColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.5).cgColor
|
||||||
|
|
||||||
|
view.layer.addSublayer(shapeLayer)
|
||||||
|
|
||||||
|
path = UIBezierPath()
|
||||||
|
path.move(to: CGPoint(x: view.frame.size.width, y: (view.frame.size.height / 2) - 64))
|
||||||
|
path.addLine(to: CGPoint(x: view.frame.size.width - 32, y: (view.frame.size.height / 2) - 64))
|
||||||
|
path.addLine(to: CGPoint(x: view.frame.size.width - 32, y: (view.frame.size.height / 2) + 64))
|
||||||
|
path.addLine(to: CGPoint(x: view.frame.size.width, y: (view.frame.size.height / 2) + 64))
|
||||||
|
path.addLine(to: CGPoint(x: view.frame.size.width, y: (view.frame.size.height / 2) - 64))
|
||||||
|
path.close()
|
||||||
|
|
||||||
|
shapeLayer = CAShapeLayer()
|
||||||
|
shapeLayer.path = path.cgPath
|
||||||
|
shapeLayer.fillColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.5).cgColor
|
||||||
|
|
||||||
|
view.layer.addSublayer(shapeLayer)
|
||||||
|
|
||||||
|
path = UIBezierPath()
|
||||||
|
path.move(to: CGPoint(x: view.frame.size.width, y: (view.frame.size.height / 2) + 64))
|
||||||
|
path.addLine(to: CGPoint(x: 0, y: (view.frame.size.height / 2) + 64))
|
||||||
|
path.addLine(to: CGPoint(x: 0, y: view.frame.size.height))
|
||||||
|
path.addLine(to: CGPoint(x: view.frame.size.width, y: view.frame.size.height))
|
||||||
|
path.addLine(to: CGPoint(x: view.frame.size.width, y: (view.frame.size.height / 2) + 64))
|
||||||
|
path.close()
|
||||||
|
|
||||||
|
shapeLayer = CAShapeLayer()
|
||||||
|
shapeLayer.path = path.cgPath
|
||||||
|
shapeLayer.fillColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.5).cgColor
|
||||||
|
|
||||||
|
view.layer.addSublayer(shapeLayer)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
|
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
|
||||||
print("User from manual input: \(textField.text)")
|
print("User from manual input: \(textField.text!)")
|
||||||
sendResult(textField.text!)
|
sendResult(textField.text!)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user