Первая

This commit is contained in:
Igor I
2023-11-06 11:50:11 +06:00
commit bf93c88af3
351 changed files with 34556 additions and 0 deletions

1
app/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/build

79
app/build.gradle Normal file
View File

@ -0,0 +1,79 @@
apply plugin: 'com.android.application'
android {
signingConfigs {
config {
keyAlias 'ASDC'
keyPassword 'firstg@h0km'
storeFile file('O:/projects/Workspace_Android/Keystore/locustkeystore')
storePassword 'locustg@h0km'
}
}
compileSdkVersion 33
defaultConfig {
applicationId "kz.istt.locust"
minSdkVersion 15
targetSdkVersion 33
versionCode 99
versionName "2.4.3"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug {
signingConfig signingConfigs.config
}
}
packagingOptions {
resources {
excludes += ['META-INF/DEPENDENCIES', 'META-INF/LICENSE']
}
}
buildToolsVersion '30.0.3'
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
namespace 'kz.istt.locust'
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.navigation:navigation-fragment:2.0.0'
implementation 'androidx.navigation:navigation-ui:2.0.0'
implementation 'com.google.android.gms:play-services-maps:17.0.0'
implementation 'com.google.android.gms:play-services-vision:20.1.2'
implementation 'com.google.android.gms:play-services-auth:20.4.0'
implementation 'com.google.maps.android:android-maps-utils:1.0.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
/*
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
implementation 'com.google.android.gms:play-services-maps:17.0.0'
implementation 'androidx.appcompat:appcompat:1.0.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
*/
/*compile files('libs/commons-codec-1.6.jar')
compile files('libs/commons-logging-1.1.1.jar')
compile files('libs/fluent-hc-4.5.2.jar')
compile files('libs/httpclient-4.5.2.jar')
compile files('libs/httpclient-cache-4.5.2.jar')
compile files('libs/httpcore-4.4.4.jar')
compile files('libs/httpmime-4.5.2.jar')*/
}

21
app/proguard-rules.pro vendored Normal file
View File

@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

BIN
app/release/app-release.apk Normal file

Binary file not shown.

View File

@ -0,0 +1,20 @@
{
"version": 3,
"artifactType": {
"type": "APK",
"kind": "Directory"
},
"applicationId": "kz.istt.locust",
"variantName": "release",
"elements": [
{
"type": "SINGLE",
"filters": [],
"attributes": [],
"versionCode": 99,
"versionName": "2.4.3",
"outputFile": "app-release.apk"
}
],
"elementType": "File"
}

View File

@ -0,0 +1,26 @@
package kz.istt.locust;
import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getTargetContext();
assertEquals("kz.istt.locust", appContext.getPackageName());
}
}

View File

@ -0,0 +1,24 @@
<resources>
<!--
TODO: Before you run your application, you need a Google Maps API key.
To get one, follow this link, follow the directions and press "Create" at the end:
https://console.developers.google.com/flows/enableapi?apiid=maps_android_backend&keyType=CLIENT_SIDE_ANDROID&r=CD:44:12:9A:81:C0:D4:4D:1B:64:9C:29:FC:9F:EC:55:4C:84:6E:E6%3Bkz.istt.locust
You can also add your credentials to an existing key, using these values:
Package name:
kz.istt.locust
SHA-1 certificate fingerprint:
CD:44:12:9A:81:C0:D4:4D:1B:64:9C:29:FC:9F:EC:55:4C:84:6E:E6
Alternatively, follow the directions here:
https://developers.google.com/maps/documentation/android/start#get-key
Once you have your key (it starts with "AIza"), replace the "google_maps_key"
string in this file.
-->
<string name="google_maps_key" templateMergeStrategy="preserve" translatable="false">AIzaSyA_tOZ-AUtAbt0GOkNgWUBtSbEZgTk4vXA</string>
</resources>

View File

@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!--
The ACCESS_COARSE/FINE_LOCATION permissions are not required to use
Google Maps Android API v2, but you must specify either coarse or fine
location permissions for the 'MyLocation' functionality.
-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!--uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/-->
<!--uses-permission android:name="android.permission.READ_USER_DICTIONARY" /-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" /> <!-- uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" / -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
<application
android:name=".Locust"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:networkSecurityConfig="@xml/network_security_config"
android:theme="@style/AppTheme"
android:requestLegacyExternalStorage="true"
>
<!-- android:requestLegacyExternalStorage Вернуть работу с файлами как в старых версиях (Для Android 11 не рабоает) -->
<!--
The API key for Google Maps-based APIs is defined as a string resource.
(See the file "res/values/google_maps_api.xml").
Note that the API key is linked to the encryption key used to sign the APK.
You need a different API key for each encryption key, including the release key that is used to
sign the APK for publishing.
You can define the keys for the debug and release targets in src/debug/ and src/release/.
-->
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="@string/google_maps_key" />
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<activity
android:name=".MapsActivity"
android:label="@string/title_activity_maps"></activity>
<activity android:name=".SplashScreen"
android:exported="true">
<intent-filter android:label="ASDC">
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".MainActivity"
android:configChanges="orientation|screenSize"
android:label="@string/app_name"></activity>
<activity
android:name=".SetupActivity"
android:configChanges="orientation|screenSize"
android:label="@string/title_activity_setup"></activity>
<activity
android:name=".ScanActivity"
android:configChanges="orientation|screenSize"
android:label="@string/Authorize_the_tablet_by_QR_code"></activity>
<activity
android:name=".LocustActivity"
android:configChanges="screenSize"
android:label="@string/title_activity_locust"/>
<activity
android:name=".LocustListActivity"
android:configChanges="orientation|screenSize"
android:label="@string/title_activity_locust_list"></activity>
<activity
android:name=".LocustDelListActivity"
android:configChanges="orientation|screenSize"
android:label="@string/title_activity_locust_del_list"></activity>
<activity
android:name=".LocustDelActivity"
android:configChanges="orientation|screenSize"
android:label="@string/title_activity_locust_del"></activity>
<!--
activity
android:name="kz.istt.locust.ImagePickActivity"
android:label="@string/title_activity_image_pick"
android:configChanges="orientation|screenSize">
</activity
-->
<!--
activity
android:name="kz.istt.locust.GeoMapActivity"
android:label="@string/title_activity_geo_map"
android:configChanges="orientation|screenSize"
android:parentActivityName="MapActivity" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="MapActivity" />
</activity
-->
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>
<service android:name=".MainService" />
<receiver android:name=".MyBroadReceiv" />
</application>
</manifest>

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

View File

@ -0,0 +1,246 @@
package dbfields;
import android.content.Context;
import android.database.Cursor;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.InputType;
import android.util.AttributeSet;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import java.util.ArrayList;
import java.util.List;
import kz.istt.locust.DbOpenHelper;
import kz.istt.locust.LocustActivity;
import kz.istt.locust.R;
import static android.widget.AdapterView.INVALID_POSITION;
public class AutoCompleteTextViewDB extends AutoCompleteTextView implements selectDB {
private String m_Value = null;
private List<String> m_lName = new ArrayList<String>(); //Заголовки
private List<String> m_lVal = new ArrayList<String>(); //Значения
public ArrayAdapter<String> dataAdapter = null;
private Context m_context = null;
private List<OnClickListener> m_lChange = new ArrayList<OnClickListener>(); //Слушатели изменений
/*private AdapterView.OnItemSelectedListener listener = new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
if (getSelectedItemPosition() != INVALID_POSITION && position != INVALID_POSITION)
AutoCompleteTextViewDB.this.setValue(m_lVal.get(getSelectedItemPosition()));
}
@Override
public void onNothingSelected(AdapterView<?> parentView) {
}
};*/
private AdapterView.OnItemClickListener listener = new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
int pos=getSelectedItemPosition();
String val=m_lVal.get(pos);
AutoCompleteTextViewDB.this.setValue(val);
}
};
int getSelectedItemPosition() {
String str = this.getText().toString();
int pos=INVALID_POSITION;
for(int i=0; i<m_lName.size();i++)
{
if(str.equals(m_lName.get(i).toString())) {
pos = i;
break;
}
}
return pos;
}
/**
* Добавить слушателя смены значения (не клика)
* @param listener
*/
public void addOnChangeValueListener(OnClickListener listener)
{
m_lChange.add(listener);
}
/**
* Удалить слушателя смены значений
* @param listener
*/
public void remOnChangeValueListener(OnClickListener listener)
{
m_lChange.remove(listener);
}
/*Консткукто*/
public AutoCompleteTextViewDB(Context context, AttributeSet attrs)
{
super(context,attrs);
m_context=context;
//setOnItemSelectedListener(listener);
setOnItemClickListener(listener);
setInputType(InputType.TYPE_NULL); //Disable writing to field
}
/**
* Получить значение
*/
public String getValue()
{
return m_Value;
}
/** Присвоить значение полю и попытаться найти его в выподающем списке*/
public void setValue(String value)
{
if(m_Value == value) return;
m_Value = value;
updatePosition();
//Информируем слушателей о изменении значении
for(int i=0;i<m_lChange.size();i++)
{ m_lChange.get(i).onClick(this);
}
}
/*public String getText(){
//
}*/
public void addField(String name, String val)
{
m_lName.add(name);
m_lVal.add(val);
//Обновляем список
//setOnItemSelectedListener(null); //Чтоб событие не сработало
setOnItemClickListener(null);
dataAdapter = new ArrayAdapter<String>(m_context, R.layout.dropdown_item, m_lName);
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
this.setAdapter(dataAdapter);
//setOnItemSelectedListener(listener);
setOnItemClickListener(listener);
updatePosition(); //Чтоб установилось на существующее значение если оно есть
}
public void clearFields()
{
m_lName.clear();
m_lVal.clear();
//Обновляем список
//setOnItemSelectedListener(null);
setOnItemClickListener(null);
dataAdapter = new ArrayAdapter<String>(m_context, R.layout.dropdown_item, m_lName);
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
this.setAdapter(dataAdapter);
//setOnItemSelectedListener(listener);
setOnItemClickListener(listener);
}
public void updateAdapter(Context context){
//Обновляем список
setOnItemClickListener(null);
dataAdapter = new ArrayAdapter<String>(context, R.layout.dropdown_item, m_lName);
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
this.setAdapter(dataAdapter);
setOnItemClickListener(listener);
}
/**
* Обновить позицию вып списка в соответствии со значением
*/
public void updatePosition()
{
Boolean b=true;
for(int i=0;i<m_lVal.size();i++)
{
if(m_lVal.get(i).equals(m_Value))
{
setText(m_lName.get(i)); //setSelection(i);
b=false;
break;
}
}
if(b) setText(""); //setSelection(INVALID_POSITION);
updateAdapter(m_context);
}
public void setOnChangeValueListener(View.OnClickListener listener){
this.addOnChangeValueListener(listener);
}
/*
// Класс для сохранения изменений сделаных пользователем при повороте экрана
public static class SavedState extends BaseSavedState
{
String value = ""; //Не может быть null почемуто вылетает!
SavedState(Parcelable superState)
{
super(superState);
}
@Override
public void writeToParcel(Parcel out, int flags)
{
super.writeToParcel(out, flags);
out.writeString(value);
}
public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>()
{
public SavedState createFromParcel(Parcel in)
{
return new SavedState(in);
}
public SavedState[] newArray(int size)
{
return new SavedState[size];
}
};
private SavedState(Parcel in)
{
super(in);
value = in.readString();
}
}
@Override
public Parcelable onSaveInstanceState()
{
SavedState st = new SavedState(super.onSaveInstanceState());
st.value = getValue();
if(st.value==null) st.value="";
return st;
}
@Override
public void onRestoreInstanceState(Parcelable state)
{
if (state == null || !(state instanceof SavedState))
{
super.onRestoreInstanceState(state);
return;
}
SavedState ss = (SavedState) state;
super.onRestoreInstanceState(ss.getSuperState());
setValue(ss.value);
};
*/
}

View File

@ -0,0 +1,246 @@
package dbfields;
import android.content.Context;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.InputFilter;
import android.text.InputType;
import android.util.AttributeSet;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import kz.istt.locust.R;
public class DateInput extends LinearLayout
{
private EditText etD = null;
private TextView tv1 = null; //Разделитель дня и месяца
private EditText etM = null;
private EditText etY = null;
//Задаёт видимость полей
public void setVisibleDMY(String val)
{
if(val.toLowerCase().indexOf("d")==-1)
{
etD.setVisibility(INVISIBLE);
if(etD.getParent()!=null) ((ViewGroup) etD.getParent()).removeView(etD);
if(tv1.getParent()!=null) ((ViewGroup) tv1.getParent()).removeView(tv1);
} else
{
etD.setVisibility(VISIBLE);
if(etD.getParent()==null) addView(etD);
if(tv1.getParent()==null) addView(tv1);
}
if(val.toLowerCase().indexOf("m")==-1)
{
etM.setVisibility(INVISIBLE);
if(etM.getParent()!=null)
((ViewGroup) etM.getParent()).removeView(etM);
if(tv1.getParent()!=null)
((ViewGroup) tv1.getParent()).removeView(tv1);
} else
{
etM.setVisibility(VISIBLE);
if(etM.getParent()==null) addView(etM);
if(tv1.getParent()==null) addView(tv1);
}
}
public DateInput(Context context, AttributeSet attr)
{
super(context, attr);
int maxLength = 10;
InputFilter[] fArray = new InputFilter[1];
fArray[0] = new InputFilter.LengthFilter(maxLength);
LinearLayout.LayoutParams paramMessage = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
paramMessage.weight = (float) 1.0;
etD = new EditText(context);
etD.setHint(context.getResources().getString(R.string.Day));
etD.setInputType(InputType.TYPE_CLASS_NUMBER);
etD.setFilters(new InputFilter[] { new InputFilter.LengthFilter(2) }); // Почему-то не работает…
etD.setMaxEms(10);
etD.setFilters(fArray);
addView(etD, paramMessage);
tv1 = new TextView(context);
tv1.setText(".");
addView(tv1);
etM = new EditText(context);
etM.setHint(context.getResources().getString(R.string.Month));
etM.setInputType(InputType.TYPE_CLASS_NUMBER);
etM.setFilters(new InputFilter[] { new InputFilter.LengthFilter(2) }); // Почему-то не работает…
etM.setMaxEms(10);
etM.setFilters(fArray);
addView(etM, paramMessage);
TextView tv = new TextView(context);
tv.setText(".");
addView(tv);
etY = new EditText(context);
etY.setHint(context.getResources().getString(R.string.Year));
etY.setInputType(InputType.TYPE_CLASS_NUMBER);
etY.setFilters(new InputFilter[] { new InputFilter.LengthFilter(4) }); // Почему-то не работает…
etY.setMaxEms(10);
etY.setMinWidth(80);
etY.setFilters(fArray);
addView(etY, paramMessage);
}
/**
* Секунд с начала 1970 года
*/
public void setDate(Long date)
{
if (date == null)
setDate((Date) null);
else
setDate(new Date(date * 1000L));
}
public void setDate(Date date)
{
if (date == null)
{
etD.setText("");
etM.setText("");
etY.setText("");
} else
{
etD.setText(new SimpleDateFormat("dd").format(date));
etM.setText(new SimpleDateFormat("MM").format(date));
etY.setText(new SimpleDateFormat("yyyy").format(date));
}
}
/**
* Получить секунд с начала 1970 года по гринвичу
*
* @return
*/
public Long getDate()
{
Date d = null;
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
try
{
String day = etD.getText().toString();
if(day.equals("") && etD.getVisibility() == INVISIBLE) day="01"; //Если не виден и не задан день то 1е число
if(!day.equals(""))
{
if(Integer.valueOf(day)<0 || Integer.valueOf(day)>31) return null;
}
String month = etM.getText().toString();
if(month.equals("") && etM.getVisibility() == INVISIBLE) month="01"; //Если не виден и не задан день то 1е число
if(!month.equals(""))
{
if(Integer.valueOf(month)<0 || Integer.valueOf(month)>12) return null;
}
String year = etY.getText().toString();
if(year.equals("") && etY.getVisibility() == INVISIBLE) year="1970";
if(!year.equals(""))
{
if(Integer.valueOf(year)<1970 || Integer.valueOf(year)>2999) return null;
}
d = sdf.parse(day + "/" + month + "/" + year);
} catch (ParseException e)
{
return null;
}
return d.getTime() / 1000L;
}
@Override
public String toString()
{
return String.valueOf(getDate());
}
@Override
public boolean isSaveEnabled()
{
return true;
}
// Класс для сохранения изменений сделаных пользователем при повороте экрана
public static class SavedStateDI extends BaseSavedState
{
//Не может быть null почемуто вылетает!
String day = "";
String month = "";
String year = "";
SavedStateDI(Parcelable superState)
{
super(superState);
}
@Override
public void writeToParcel(Parcel out, int flags)
{
super.writeToParcel(out, flags);
out.writeString(day);
out.writeString(month);
out.writeString(year);
}
public static final Parcelable.Creator<SavedStateDI> CREATOR = new Parcelable.Creator<SavedStateDI>()
{
public SavedStateDI createFromParcel(Parcel in)
{
return new SavedStateDI(in);
}
public SavedStateDI[] newArray(int size)
{
return new SavedStateDI[size];
}
};
private SavedStateDI(Parcel in)
{
super(in);
day = in.readString();
month = in.readString();
year = in.readString();
}
}
@Override
protected Parcelable onSaveInstanceState()
{
SavedStateDI st = new SavedStateDI(super.onSaveInstanceState());
st.day = etD.getText().toString();
st.month = etM.getText().toString();
st.year = etY.getText().toString();
return st;
}
@Override
protected void onRestoreInstanceState(Parcelable state)
{
if (state == null || !(state instanceof SavedStateDI))
{
super.onRestoreInstanceState(state);
return;
}
SavedStateDI ss = (SavedStateDI) state;
super.onRestoreInstanceState(ss.getSuperState());
etD.setText(ss.day);
etM.setText(ss.month);
etY.setText(ss.year);
};
}

View File

@ -0,0 +1,109 @@
package dbfields;
import android.content.Context;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.widget.EditText;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateTimeTM extends com.google.android.material.textfield.TextInputEditText implements fieldDB
{
private String m_Value = null;
public DateTimeTM(Context context)
{
super(context);
}
public DateTimeTM(Context context, AttributeSet attrs)
{
super(context,attrs);
}
public String getValue(){
return m_Value;
}
//Передаётся в секундах с 1970 года по гринвичу но отображается в локальном времени 1579154400 отображается 16.01.2020 12:00 (в Алмате)
public void setValue(String val)
{
m_Value = val;
if(val!=null && !val.equals(""))
{
Date date = new Date(Long.parseLong(m_Value)*1000);
SimpleDateFormat format = new SimpleDateFormat("dd.MM.yyyy HH:mm");
//format.setTimeZone(TimeZone.getTimeZone("UTC"));
String str = format.format(date);
setText(str);
}else
{
setText("");
}
}
// Класс для сохранения изменений сделаных пользователем при повороте экрана
public static class SavedStateTDTM extends BaseSavedState
{
String value = ""; //Не может быть null почемуто вылетает!
SavedStateTDTM(Parcelable superState)
{
super(superState);
}
@Override
public void writeToParcel(Parcel out, int flags)
{
super.writeToParcel(out, flags);
out.writeString(value);
}
public static final Creator<SavedStateTDTM> CREATOR = new Creator<SavedStateTDTM>()
{
public SavedStateTDTM createFromParcel(Parcel in)
{
return new SavedStateTDTM(in);
}
public SavedStateTDTM[] newArray(int size)
{
return new SavedStateTDTM[size];
}
};
private SavedStateTDTM(Parcel in)
{
super(in);
value = in.readString();
}
}
@Override
public Parcelable onSaveInstanceState()
{
SavedStateTDTM st = new SavedStateTDTM(super.onSaveInstanceState());
st.value = getValue();
if(st.value==null) st.value="";
return st;
}
@Override
public void onRestoreInstanceState(Parcelable state)
{
if (state == null || !(state instanceof SavedStateTDTM))
{
super.onRestoreInstanceState(state);
return;
}
SavedStateTDTM ss = (SavedStateTDTM) state;
super.onRestoreInstanceState(ss.getSuperState());
setValue(ss.value);
};
}

View File

@ -0,0 +1,110 @@
package dbfields;
import android.content.Context;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.widget.EditText;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateTimeText extends EditText implements fieldDB
{
private String m_Value = null;
public DateTimeText(Context context)
{
super(context);
}
public DateTimeText(Context context, AttributeSet attrs)
{
super(context,attrs);
}
public String getValue(){
return m_Value;
}
//Передаётся в секундах с 1970 года по гринвичу но отображается в локальном времени 1579154400 отображается 16.01.2020 12:00 (в Алмате)
public void setValue(String val)
{
m_Value = val;
if(val!=null && !val.equals(""))
{
Date date = new Date(Long.parseLong(m_Value)*1000);
SimpleDateFormat format = new SimpleDateFormat("dd.MM.yyyy HH:mm");
//format.setTimeZone(TimeZone.getTimeZone("UTC"));
String str = format.format(date);
setText(str);
}else
{
setText("");
}
}
// Класс для сохранения изменений сделаных пользователем при повороте экрана
public static class SavedStateDTT extends BaseSavedState
{
String value = ""; //Не может быть null почемуто вылетает!
SavedStateDTT(Parcelable superState)
{
super(superState);
}
@Override
public void writeToParcel(Parcel out, int flags)
{
super.writeToParcel(out, flags);
out.writeString(value);
}
public static final Parcelable.Creator<SavedStateDTT> CREATOR = new Parcelable.Creator<SavedStateDTT>()
{
public SavedStateDTT createFromParcel(Parcel in)
{
return new SavedStateDTT(in);
}
public SavedStateDTT[] newArray(int size)
{
return new SavedStateDTT[size];
}
};
private SavedStateDTT(Parcel in)
{
super(in);
value = in.readString();
}
}
@Override
public Parcelable onSaveInstanceState()
{
SavedStateDTT st = new SavedStateDTT(super.onSaveInstanceState());
st.value = getValue();
if(st.value==null) st.value="";
return st;
}
@Override
public void onRestoreInstanceState(Parcelable state)
{
if (state == null || !(state instanceof SavedStateDTT))
{
super.onRestoreInstanceState(state);
return;
}
SavedStateDTT ss = (SavedStateDTT) state;
super.onRestoreInstanceState(ss.getSuperState());
setValue(ss.value);
};
}

View File

@ -0,0 +1,33 @@
package dbfields;
import android.text.InputFilter;
import android.text.Spanned;
public class InputFilterMinMax implements InputFilter {
private int min, max;
public InputFilterMinMax(int min, int max) {
this.min = min;
this.max = max;
}
public InputFilterMinMax(String min, String max) {
this.min = Integer.parseInt(min);
this.max = Integer.parseInt(max);
}
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
try {
int input = Integer.parseInt(dest.toString() + source.toString());
if (isInRange(min, max, input))
return null;
} catch (NumberFormatException nfe) { }
return "";
}
private boolean isInRange(int a, int b, int c) {
return b > a ? c >= a && c <= b : c >= b && c <= a;
}
}

View File

@ -0,0 +1,213 @@
package dbfields;
import android.content.Context;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.Editable;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
import android.util.AttributeSet;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import java.util.ArrayList;
import java.util.List;
public class SpinnerDB extends Spinner implements selectDB
{
private String m_Value = null;
private List<String> m_lName = new ArrayList<String>(); //Заголовки
private List<String> m_lVal = new ArrayList<String>(); //Значения
private Context m_context = null;
private List<OnClickListener> m_lChange = new ArrayList<OnClickListener>(); //Слушатели изменений
private OnItemSelectedListener listener = new OnItemSelectedListener()
{
@Override
public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id)
{
if(getSelectedItemPosition()!=INVALID_POSITION && position != INVALID_POSITION)
SpinnerDB.this.setValue(m_lVal.get(getSelectedItemPosition()));
}
@Override
public void onNothingSelected(AdapterView<?> parentView)
{
}
};
/**
* Добавить слушателя смены значения (не клика)
* @param listener
*/
public void addOnChangeValueListener(OnClickListener listener)
{
m_lChange.add(listener);
}
/**
* Удалить слушателя смены значений
* @param listener
*/
public void remOnChangeValueListener(OnClickListener listener)
{
m_lChange.remove(listener);
}
public SpinnerDB(Context context, AttributeSet attrs)
{
super(context,attrs);
m_context = context;
setOnItemSelectedListener(listener);
}
/**
* Получить значение
*/
public String getValue()
{
return m_Value;
}
/** Присвоить значение полю и попытаться найти его в выподающем списке*/
public void setValue(String value)
{
if(m_Value == value) return;
m_Value = value;
updatePosition();
//Информируем слушателей о изменении значении
for(int i=0;i<m_lChange.size();i++)
{ m_lChange.get(i).onClick(getEmptyView());
}
}
public void addField(String name, String val)
{
m_lName.add(name);
m_lVal.add(val);
//Обновляем список
setOnItemSelectedListener(null); //Чтоб событие не сработало
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(m_context, android.R.layout.simple_spinner_item, m_lName);
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
this.setAdapter(dataAdapter);
setOnItemSelectedListener(listener);
updatePosition(); //Чтоб установилось на существующее значение если оно есть
}
public void clearFields()
{
m_lName.clear();
m_lVal.clear();
//Обновляем список
setOnItemSelectedListener(null);
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(m_context, android.R.layout.simple_spinner_item, m_lName);
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
this.setAdapter(dataAdapter);
setOnItemSelectedListener(listener);
}
/**
* Обновить позицию вып списка в соответствии со значением
*/
protected void updatePosition()
{
Boolean b=true;
for(int i=0;i<m_lVal.size();i++)
{
if(m_lVal.get(i).equals(m_Value))
{
setSelection(i);
b=false;
break;
}
}
if(b) setSelection(INVALID_POSITION);
}
// Return the currently selected title (not a value)
public Editable getText(){
String result="";
for(int i=0;i<m_lVal.size();i++)
{
if(m_lVal.get(i).equals(m_Value))
{
result=m_lName.get(i);
break;
}
}
return new SpannableStringBuilder(result);
}
public void setOnChangeValueListener(View.OnClickListener listener){
this.addOnChangeValueListener(listener);
}
// Класс для сохранения изменений сделаных пользователем при повороте экрана
public static class SavedStateSPNR extends BaseSavedState
{
String value = ""; //Не может быть null почемуто вылетает!
SavedStateSPNR(Parcelable superState)
{
super(superState);
}
@Override
public void writeToParcel(Parcel out, int flags)
{
super.writeToParcel(out, flags);
out.writeString(value);
}
public static final Parcelable.Creator<SavedStateSPNR> CREATOR = new Parcelable.Creator<SavedStateSPNR>()
{
public SavedStateSPNR createFromParcel(Parcel in)
{
return new SavedStateSPNR(in);
}
public SavedStateSPNR[] newArray(int size)
{
return new SavedStateSPNR[size];
}
};
private SavedStateSPNR(Parcel in)
{
super(in);
value = in.readString();
}
}
@Override
public Parcelable onSaveInstanceState()
{
SavedStateSPNR st = new SavedStateSPNR(super.onSaveInstanceState());
st.value = getValue();
if(st.value==null) st.value="";
return st;
}
@Override
public void onRestoreInstanceState(Parcelable state)
{
if (state == null || !(state instanceof SavedStateSPNR))
{
super.onRestoreInstanceState(state);
return;
}
SavedStateSPNR ss = (SavedStateSPNR) state;
super.onRestoreInstanceState(ss.getSuperState());
setValue(ss.value);
};
}

View File

@ -0,0 +1,27 @@
package dbfields;
public class StringDB implements fieldDB
{
private String value;
public StringDB(String val)
{
value = val;
}
public StringDB(){}
@Override
public String getValue()
{
return value;
}
@Override
public void setValue(String val)
{
value=val;
}
}

View File

@ -0,0 +1,33 @@
package dbfields;
import android.content.Context;
import android.text.Html;
import android.util.AttributeSet;
import android.widget.TextView;
public class TextViewHTML extends TextView
{
public TextViewHTML(Context context, AttributeSet attrs, int defStyleAttr)
{
super(context, attrs, defStyleAttr);
init();
}
public TextViewHTML(Context context)
{
super(context);
init();
}
public TextViewHTML(Context context, AttributeSet attrs)
{
super(context, attrs);
init();
}
private void init()
{
setText(Html.fromHtml(getText().toString()));
}
}

View File

@ -0,0 +1,151 @@
package dbfields;
import android.content.Context;
import android.text.InputFilter;
import android.text.InputType;
import android.util.AttributeSet;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import kz.istt.locust.R;
public class TimeInput extends LinearLayout {
private EditText etH = null;
private TextView tv1 = null;
private EditText etM = null;
//private EditText etS = null; //Закоментил потому что секунды ненужны
//Задаёт видимость полей
public void setVisibleHMS(String val)
{
if(val.toLowerCase().indexOf("h")==-1)
{
if(etH.getParent()!=null)
((ViewGroup) etH.getParent()).removeView(etH);
if(tv1.getParent()!=null)
((ViewGroup) tv1.getParent()).removeView(tv1);
} else
{
if(etH.getParent()==null) addView(etH);
if(tv1.getParent()==null) addView(tv1);
}
if(val.toLowerCase().indexOf("m")==-1)
{
if(etM.getParent()!=null)
((ViewGroup) etM.getParent()).removeView(etM);
if(tv1.getParent()!=null)
((ViewGroup) tv1.getParent()).removeView(tv1);
} else
{
if(etM.getParent()==null) addView(etM);
if(tv1.getParent()==null) addView(tv1);
}
}
public TimeInput(Context context, AttributeSet attr) {
super(context, attr);
int maxLength = 10;
InputFilter[] fArray = new InputFilter[1];
fArray[0] = new InputFilter.LengthFilter(maxLength);
LinearLayout.LayoutParams paramMessage = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
paramMessage.weight = (float) 1.0;
etH = new EditText(context);
etH.setHint(context.getResources().getString(R.string.Hours));
etH.setInputType(InputType.TYPE_CLASS_NUMBER);
etH.setFilters(new InputFilter[] {new InputFilter.LengthFilter(4)}); //Почему-то не работает…
etH.setMaxEms(10);
etH.setFilters(fArray);
addView(etH,paramMessage);
tv1 = new TextView(context);
tv1.setText(":");
addView(tv1);
etM = new EditText(context);
etM.setHint(context.getResources().getString(R.string.Minutes));
etM.setInputType(InputType.TYPE_CLASS_NUMBER);
etM.setFilters(new InputFilter[] {new InputFilter.LengthFilter(4)}); //Почему-то не работает…
etM.setMaxEms(10);
etM.setFilters(fArray);
addView(etM/*,paramMessage*/);
/*
tv = new TextView(context);
tv.setText(":");
addView(tv);
etS = new EditText(context);
etS.setHint(context.getResources().getString(R.string.Seconds));
etS.setInputType(InputType.TYPE_CLASS_NUMBER);
etS.setFilters(new InputFilter[] {new InputFilter.LengthFilter(4)}); //Почему-то не работает…
etS.setMaxEms(10);
etS.setFilters(fArray);
addView(etS,paramMessage);
*/
}
/**
* Секунд с начала дня
*/
public void setTime(Long time)
{
if(time == null) setTime((Date)null);
else setTime(new Date(time * 1000L));
}
public void setTime(Date time)
{
if(time == null)
{
etH.setText("");
etM.setText("");
//etS.setText("");
}else
{
etH.setText(new SimpleDateFormat("HH").format(time));
etM.setText(new SimpleDateFormat("mm").format(time));
//etS.setText(new SimpleDateFormat("ss").format(time));
}
}
/**
* Получить секунд с начала дня по гринвичу с учётом временой зоны
* @return
*/
public Long getTime()
{
Date d=null;
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
sdf.setTimeZone(TimeZone.getDefault());
try
{
//d = sdf.parse(etH.getText().toString()+":"+etM.getText().toString()+":"+etS.getText().toString());
String h = etH.getText().toString();
if(h=="") h="00";
String m = etM.getText().toString();
if(m=="") m="00";
//String s = etS.getText().toString();
//if(s=="") s="00";
d = sdf.parse(h+":"+m+":00");
} catch (ParseException e) {
return null;
}
return d.getTime() / 1000L;
}
}

View File

@ -0,0 +1,13 @@
package dbfields;
import android.view.View;
import kz.istt.locust.LocustActivity;
public interface fieldDB
{
public String getValue();
public void setValue(String val);
}

View File

@ -0,0 +1,13 @@
package dbfields;
import android.text.Editable;
import android.view.View;
import dbfields.fieldDB;
public interface selectDB extends fieldDB {
public void addField(String name, String val);
public void clearFields(); //Clear all fields from drop down list
public Editable getText();
public void setOnChangeValueListener(View.OnClickListener listener);
}

View File

@ -0,0 +1,284 @@
package kz.istt.locust;
//import android.content.Context;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Spinner;
import com.google.android.material.textfield.TextInputEditText;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import dbfields.DateInput;
import dbfields.DateTimeText;
import dbfields.DateTimeTM;
import dbfields.SpinnerDB;
import dbfields.AutoCompleteTextViewDB;
import dbfields.StringDB;
/*
* Соответствие GUI полей и полей базы данных
* Для сохранения значений и для их загрузки из базы
*/
public class DBGUITable
{
private Context m_context;
//private DbOpenHelper m_dboh;
//Для списка полей
private List<Object> m_listO;
private List<String> m_listN; //Имена столбцов
private String m_table;
public DBGUITable(Context context, String table)
{
m_context = context;
m_table = table;
//m_dboh = dboh;
m_listO = new ArrayList<Object>();
m_listN = new ArrayList<String>();
}
/**
* Получить тип столбца из таблицы
* @param name
* @return
*/
public String getType(String name)
{
String type=null;
//Считываем поля и их типы из таблицы
DbOpenHelper dboh = new DbOpenHelper(m_context);
Cursor cursor = dboh.getReadableDatabase().rawQuery("PRAGMA table_info('"+m_table+"');",null);
if(cursor.moveToFirst())
{
do{
if(Tools.getStringFromCursor(cursor,"name").equals(name))
{
type = Tools.getStringFromCursor(cursor,"type");
break;
}
}while (cursor.moveToNext());
}
cursor.close();
dboh.close();
return type;
}
/*
* Передаётся компонент и название поля таблицы
*/
public void add(Object component, String name)
{
m_listO.add(component);
m_listN.add(name);
}
/**
* Найти компонент по имени поля базы
* @param fieldName
* @return
*/
public Object findComponent(String fieldName)
{
for(int i=0;i<m_listN.size();i++)
{
if(m_listN.get(i).equals(fieldName)) return m_listO.get(i);
}
return null;
}
/* Вставить либо обновить запись из GUI элементов
* */
public String write()
{
ContentValues cv = new ContentValues();
for(int i=0;i<m_listO.size();i++)
{
String field = m_listN.get(i);
String value = getValue(m_listO.get(i));
String type = getType(field);
if(type==null) {
Log.e("CCALM", "NOT FIND field = " + m_listN.get(i) + " value = " + value);
continue;
}
Log.e("CCALM", "field = " + m_listN.get(i) + " value = " + value + " type = " + type);
if(type.equals("text"))
{
cv.put(field, value);
}else
if(type.equals("integer") || type.equals("boolean"))
{
Integer val=null;
if(value!=null) val= Integer.parseInt(value);
cv.put(field, val);
}else
if(type.equals("double") || type.equals("float"))
{
Double val=null;
if(value!=null) val= Double.parseDouble(value);
cv.put(field, val);
}else
{
Log.e("CCALM", "type= " + type + " = " + value);
}
}
cv.put("send", 0); //Ставим признак не отправленности чтоб запись отправилась по расписанию
String uid=null;
//Проверка нужно ли вставить либо обновить по id записи
boolean b=false;
DbOpenHelper dboh = new DbOpenHelper(m_context);
Cursor cursor;
if(cv.getAsString("uid")!=null)
{
uid=cv.getAsString("uid");
String sql="select 1 from "+m_table+" where uid = '" + uid +"'";
cursor = dboh.getReadableDatabase().rawQuery(sql,null);
b=cursor.moveToFirst();
cursor.close();
}
dboh.close();
if(!b) //Вставляем новую запись
{
uid = UUID.randomUUID().toString().replace("-", "");
cv.put("uid", uid);
SQLiteDatabase db = dboh.getWritableDatabase();
db.beginTransaction(); //Вроде как защита от многопоточности (для сервиса)
try {
db.insert(m_table, null, cv);
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
db.close();
}else //Обновить запись
{
SQLiteDatabase db = dboh.getWritableDatabase();
db.beginTransaction(); //Вроде как защита от многопоточности (для сервиса)
uid=cv.getAsString("uid");
try {
db.update(m_table, cv, "uid = ?", new String[] {uid});
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
db.close();
}
return uid;
}
/** Прочитать значения в GUI поля из базы по id записи
*/
public void read(String uid)
{
if (uid != null) // Выборка данных для редактирования
{
DbOpenHelper dboh = new DbOpenHelper(m_context);
String sql = "";
Cursor cursor = null;
sql = "select * from "+m_table+" where uid='" + uid + "'";
cursor = dboh.getReadableDatabase().rawQuery(sql, null);
if (cursor.moveToFirst())
{
//перебираем столбцы и вставляем значения в поля
for(int i=0;i<cursor.getColumnCount();i++)
{
Object obj=findComponent(cursor.getColumnName(i));
if(obj!=null)
{
Log.e("CCALM", "1 field " + cursor.getColumnName(i) + " = " + cursor.getString(i) + " type= " + cursor.getType(i));
if(cursor.getType(i)==2){ //Because cutting double
setValue(obj, ""+cursor.getDouble(i));
}else {
setValue(obj, cursor.getString(i));
}
//для проверки обратное дёйствие
//Log.e("CCALM", "2 field " + cursor.getColumnName(i) + " = " + getValue(findComponent(cursor.getColumnName(i))));
}
}
}
cursor.close();
dboh.close();
}
}
//Прочитать значение из GUI объекта "obj"
public String getValue(Object obj)
{
String value = null;
if(obj!=null)
{
if(obj.getClass().toString().indexOf("android.widget.EditText")!=-1) value = ((EditText)obj).getText().toString(); else
if(obj.getClass().toString().indexOf("android.material.textfield.TextInputEditText")!=-1) value = ((TextInputEditText)obj).getText().toString(); else
if(obj.getClass().toString().indexOf("android.widget.Spinner")!=-1) value = ((Spinner)obj).getSelectedItem().toString(); else
if(obj.getClass().toString().indexOf("android.widget.CheckBox")!=-1) value = ((CheckBox)obj).isChecked() ? "1" : "0"; else
if(obj.getClass().toString().indexOf("java.lang.Integer")!=-1) value = ((Integer)obj).toString(); else
if(obj.getClass().toString().indexOf("java.lang.String")!=-1) value = ((String)obj); else
if(obj.getClass().toString().indexOf("dbfields.SpinnerDB")!=-1) value = ((SpinnerDB)obj).getValue(); else
if(obj.getClass().toString().indexOf("dbfields.AutoCompleteTextViewDB")!=-1) value = ((AutoCompleteTextViewDB)obj).getValue(); else
if(obj.getClass().toString().indexOf("dbfields.StringDB")!=-1) value = ((StringDB)obj).getValue(); else
if(obj.getClass().toString().indexOf("dbfields.DateTimeTM")!=-1) value = ((DateTimeTM)obj).getValue(); else
if(obj.getClass().toString().indexOf("dbfields.DateTimeText")!=-1) value = ((DateTimeText)obj).getValue(); else
if(obj.getClass().toString().indexOf("dbfields.DateInput")!=-1)
{
if(((DateInput)obj).getDate()!=null)
value = ((DateInput)obj).getDate().toString(); //В секундах
}
}
if(value!=null && value.equals("")) value=null;
return value;
}
//Установить значение "value" для GUI объекта "obj"
public void setValue(Object obj, String value)
{
if(obj==null) return;
//Log.d("igor","getClass = "+obj.getClass().toString());
if(obj.getClass().toString().indexOf("android.widget.EditText")!=-1) ((EditText)obj).setText(value);
if(obj.getClass().toString().indexOf("android.material.textfield.TextInputEditText")!=-1) ((TextInputEditText)obj).setText(value);
if(obj.getClass().toString().indexOf("android.widget.Spinner")!=-1) Tools.selSpinnerIC(((Spinner)obj), value);
if(obj.getClass().toString().indexOf("android.widget.CheckBox")!=-1) ((CheckBox)obj).setChecked(value.equals("1") ? true : false);
//if(obj.getClass().toString().indexOf("java.lang.Integer")!=-1) ((Integer)obj)=Integer.parseInt(value); так не работает
//if(obj.getClass().toString().indexOf("java.lang.String")!=-1) ((String)obj)=value; так не работает
if(obj.getClass().toString().indexOf("dbfields.SpinnerDB")!=-1) ((SpinnerDB)obj).setValue(value);
if(obj.getClass().toString().indexOf("dbfields.AutoCompleteTextViewDB")!=-1) ((AutoCompleteTextViewDB)obj).setValue(value);
if(obj.getClass().toString().indexOf("dbfields.StringDB")!=-1) ((StringDB)obj).setValue(value);
if(obj.getClass().toString().indexOf("dbfields.DateTimeTM")!=-1) ((DateTimeTM)obj).setValue(value);
if(obj.getClass().toString().indexOf("dbfields.DateTimeText")!=-1) ((DateTimeText)obj).setValue(value);
if(obj.getClass().toString().indexOf("dbfields.DateInput")!=-1)
{
if(value==null)
{ ((DateInput)obj).setDate((Date)null);
}
else
{ ((DateInput)obj).setDate(Long.parseLong(value));
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,40 @@
package kz.istt.locust;
import android.os.Parcel;
import android.os.Parcelable;
public class LatLon implements android.os.Parcelable{
public double lat;
public double lon;
public static final Parcelable.Creator<LatLon> CREATOR = new Parcelable.Creator<LatLon>() {
@Override
public LatLon createFromParcel(Parcel source) {
double lat = source.readDouble();
double lon = source.readDouble();
return new LatLon(lat, lon);
}
@Override
public LatLon[] newArray(int size) {
return new LatLon[size];
}
};
LatLon(double lat, double lon){
this.lat=lat;
this.lon=lon;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeDouble(lat);
dest.writeDouble(lon);
}
}

View File

@ -0,0 +1,145 @@
package kz.istt.locust;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.ArrayList;
import java.util.Locale;
import tools.LatLonListener;
public class LatLonAdapter extends ArrayAdapter<LatLon> {
private LayoutInflater inflater;
private int layout;
public ArrayList<LatLon> latlonList;
LatLonListener latlonListener=null;
ListView productList=null;
View.OnClickListener clc=null;
LatLonAdapter(Context context, int resource, ArrayList<LatLon> latlon, LatLonListener latlonListener, ListView productList) {
super(context, resource, latlon);
this.latlonList = latlon;
this.layout = resource;
this.inflater = LayoutInflater.from(context);
this.latlonListener = latlonListener;
}
@Override
public int getCount(){
return latlonList.size();
}
/*public void addItem(LatLon item) {
this.latlonList.add(item);
this.notifyDataSetChanged();
}*/
/*@Override
public void notifyDataSetChanged() {
//ViewGroup.LayoutParams par = productList.getLayoutParams();
//RelativeLayout.LayoutParams mParam = new RelativeLayout.LayoutParams(par.width,par.height+100);
//productList.setLayoutParams(mParam);
}*/
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder viewHolder;
if(convertView==null){
convertView = inflater.inflate(this.layout, parent, false);
viewHolder = new ViewHolder(convertView);
convertView.setTag(viewHolder);
}
else{
viewHolder = (ViewHolder) convertView.getTag();
}
final LatLon latlon = latlonList.get(position);
DecimalFormatSymbols custom = new DecimalFormatSymbols(new Locale("en", "US"));
custom.setDecimalSeparator('.');
DecimalFormat df = new DecimalFormat("0.0000000");
df.setDecimalFormatSymbols(custom);
if(viewHolder.edtLat!=null) {
if (latlon.lat == 0) viewHolder.edtLat.setText("");
else viewHolder.edtLat.setText(df.format(latlon.lat));
}
if(viewHolder.edtLon!=null) {
if (latlon.lon == 0) viewHolder.edtLon.setText("");
else viewHolder.edtLon.setText(df.format(latlon.lon));
}
if(viewHolder.btnDelGPS!=null) {
viewHolder.btnDelGPS.setOnClickListener(new OnClickListenerIDDEL(position, this));
}
if(viewHolder.btnGetGPS!=null) {
viewHolder.btnGetGPS.setOnClickListener(new OnClickListenerIDADD(position, this));
}
return convertView;
}
private class ViewHolder {
final com.google.android.material.button.MaterialButton btnGetGPS, btnDelGPS;
final com.google.android.material.textfield.TextInputEditText edtLat, edtLon;
ViewHolder(View view){
btnGetGPS = view.findViewById(R.id.btnGetGPS);
btnDelGPS = view.findViewById(R.id.btnDelGPS);
edtLat = view.findViewById(R.id.edtLat);
edtLon = view.findViewById(R.id.edtLon);
}
}
//To add an element to a list
class OnClickListenerIDADD implements View.OnClickListener{
int position;
LatLonAdapter adapter;
OnClickListenerIDADD(int position,LatLonAdapter adapter){
this.position=position;
this.adapter=adapter;
}
@Override
public void onClick(View view) {
LatLon latlon = adapter.latlonList.get(position);
latlon.lat=adapter.latlonListener.getLat();
latlon.lon=adapter.latlonListener.getLon();
if(adapter.latlonList.get(adapter.latlonList.size()-1).lat!=0 && adapter.latlonList.get(adapter.latlonList.size()-1).lon!=0){
adapter.latlonList.add(new LatLon(0, 0));
if(adapter.clc!=null){
adapter.clc.onClick(null);
}
}
adapter.notifyDataSetChanged();
}
}
//To remove an element from a list
class OnClickListenerIDDEL implements View.OnClickListener{
int position;
LatLonAdapter adapter;
OnClickListenerIDDEL(int position,LatLonAdapter adapter){
this.position=position;
this.adapter=adapter;
}
@Override
public void onClick(View view) {
LatLon latlon = adapter.latlonList.get(position);
latlon.lat=0;
latlon.lon=0;
if(latlonList.size()>1 && position!=latlonList.size()-1) {
latlonList.remove(position);
if(adapter.clc!=null){
adapter.clc.onClick(null);
}
}
adapter.notifyDataSetChanged();
}
}
}

View File

@ -0,0 +1,22 @@
package kz.istt.locust;
import android.app.Application;
import android.content.res.Configuration;
public class Locust extends Application
{
@Override
public void onCreate() {
Tools.loadLocale(this);
}
@Override
public void onConfigurationChanged(Configuration newConfig)
{
super.onConfigurationChanged(newConfig);
//Задаём ещё раз локализацию, так как андроид сам меняет локализацию в соответствии с системными настройками.
Tools.loadLocale(this);
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,682 @@
package kz.istt.locust;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.Settings;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.Spinner;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class LocustDelListActivity extends AppCompatActivity
{
public LinearLayout llList;
public MyButton btn;
public FloatingActionButton btnAdd = null;
public Spinner spiList = null;
private Timer timer = new Timer();
public File file = null;
public void alert(String text)
{
AlertDialog.Builder adb = new AlertDialog.Builder(this,R.style.AlertDialogTheme);
adb.setTitle(getString(R.string.Warning));
adb.setMessage(text);
adb.setPositiveButton("OK", new DialogInterface.OnClickListener() //Кнопка открыть
{
@Override
public void onClick(DialogInterface arg0, int arg1)
{}
});
AlertDialog ad = adb.show();
ad.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(Color.BLACK);
}
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_locust_del_list);
//Загрузка сохранёного языка
Tools.loadLocale(this);
llList = (LinearLayout) findViewById(R.id.llList);
/*
* btn = (Button) findViewById(R.id.button1); OnClickListener oclBtnRus = new OnClickListener() {
*
* @Override public void onClick(View v) { //Отобразим окно уничтожения саранчи Intent intent = new Intent(LocustDelListActivity.this, LocustDelActivity.class); //intent.putExtra("id", b.id); //intent.putExtra("date", b.date); startActivity(intent); } }; btn.setOnClickListener(oclBtnRus);
*/
spiList = (Spinner) findViewById(R.id.spiList); // Оператор (пилот, водитель, др...)
ArrayList<String> list = new ArrayList<String>();
list.add(getString(R.string.Waiting_to_be_filled));
list.add(getString(R.string.Not_submitted));
list.add(getString(R.string.Submitted));
list.add(getString(R.string.All));
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, list);
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spiList.setAdapter(dataAdapter);
spiList.setOnItemSelectedListener(new OnItemSelectedListener()
{
@Override
public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id)
{
//onStart();
updateList();
}
@Override
public void onNothingSelected(AdapterView<?> parentView)
{
}
});
btnAdd = (FloatingActionButton) findViewById(R.id.btnAdd);
btnAdd.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent(LocustDelListActivity.this, LocustDelActivity.class);
startActivity(intent);
}
});
//Чтоб список обновлялся раз в минуту в соответствии с текущем фильтром (для наглядности отправки данных)
timer.scheduleAtFixedRate(new TimerTask()
{
@SuppressLint("HandlerLeak")
private Handler myHandle = new Handler() {
@Override
public void handleMessage(Message msg)
{
//onStart();
updateList();
}
};
@Override
public void run() {
myHandle.sendMessage(myHandle.obtainMessage());
}
}, 0, 1000 ); //Раз в секунду
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.locust_del_list, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
switch (item.getItemId())
{
case R.id.itemCreate: // Создание карточки
Intent intent = new Intent(this, LocustDelActivity.class);
startActivity(intent);
break;
case R.id.itemDelete: //Удаление всех отправленных из базы
AlertDialog.Builder alertDialog = new AlertDialog.Builder(LocustDelListActivity.this,R.style.AlertDialogTheme);//new AlertDialog.Builder(this).create();
alertDialog.setCancelable(false);
alertDialog.setTitle(getString(R.string.Warning));
alertDialog.setMessage(getString(R.string.Cleaning));
alertDialog.setPositiveButton(getString(R.string.action_delete), new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int arg1)
{
DbOpenHelper dboh = new DbOpenHelper(LocustDelListActivity.this);
dboh.getReadableDatabase().execSQL("delete from frmlocustdel where send=1");
dboh.close();
LocustDelListActivity.this.onStart();
}
});
alertDialog.setNegativeButton(getString(R.string.Cancel), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int arg1)
{
dialog.cancel();
}
});
AlertDialog ad = alertDialog.show();
ad.getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(Color.BLACK);
ad.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(Color.BLACK);
break;
/* case R.id.itemExport: // Экспорт в Excel всего что накопилось
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss dd.MM.yyyy");
DbOpenHelper dboh = new DbOpenHelper(this);
SQLiteDatabase db = dboh.getReadableDatabase();
String user = "";
Cursor cursor = db.rawQuery("select name,surname,patronymic from _user where del=0;", null);
if (cursor.moveToFirst())
{
user = cursor.getString(cursor.getColumnIndex("surname")) + " " + cursor.getString(cursor.getColumnIndex("name")) + " "
+ cursor.getString(cursor.getColumnIndex("patronymic"));
}
cursor.close();
String html = "";
html += "<html>\n";
html += " <head>\n";
html += " <title>Locust</title>\n";
html += " <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n";
html += " <style>td {mso-number-format: \"\\@\";}</style>";
html += " </head>\n";
html += " <body>\n";
html += "<b>" + getString(R.string.title_activity_locust_del) + ": </b><br>";
html += "<b>" + getString(R.string.Date) + ": </b><i>" + sdf.format(new Date()) + "</i><br>";
html += "<b>" + getString(R.string.User) + ": </b>" + user;
html += " <table border=\"1\" cellspacing=\"0\">\n";
html += " <caption><b>" + getString(R.string.Attributes) + "</b></caption>\n";
html += " <thead>\n";
html += " <tr>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\" style=\"text-align: center\">&nbsp;</td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\" style=\"text-align: center\" colspan=\"4\">&nbsp;</td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\" style=\"text-align: center\" colspan=\"7\"><b>" + getString(R.string.CONTROL_LOCATION) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\" style=\"text-align: center\" colspan=\"6\"><b>" + getString(R.string.VEGETATION_DATA) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\" style=\"text-align: center\" colspan=\"10\"><b>" + getString(R.string.INSECTICIDE_DATA) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\" style=\"text-align: center\" colspan=\"12\"><b>" + getString(R.string.WEATHER_CONDITIONS) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\" style=\"text-align: center\" colspan=\"7\"><b>" + getString(R.string.LOCUST_INFORMATION_INCLUDING_EGG_PODS) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\" style=\"text-align: center\" colspan=\"17\"><b>" + getString(R.string.SPRAY_APPLICATION) + "</b></td>"; //СВЕДЕНИЯ ПО ОПРЫСКИВАНИЮ
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\" style=\"text-align: center\" colspan=\"3\"><b>" + getString(R.string.EFFECTIVENESS) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\" style=\"text-align: center\" colspan=\"5\"><b>" + getString(R.string.SAFETY_AND_ENVIRONMENT) + "</b></td>";
//html += "<td bgcolor=\"#d1d1d1\" width=\"100px\" style=\"text-align: center\" colspan=\"1\">&nbsp;</td>";
html += " </tr>";
html += " <tr>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>№</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Country) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Region) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Area) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Rural_district) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Name_of_survey_team_leader) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Date) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Village) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Lat) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Lon) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Area_infested) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Area_treated) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Vegetation_type) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Height_cm) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Vegetation_crops) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Vegetation_cover) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Damage) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Veg_damage_area) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Trade_name) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.The_active_substance) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Concentration) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Formulation) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Dose_rate) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Rate_of_working_solution) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Expiry_date) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Is_insecticide_mixed_with_water_or_solvent) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.If_yes_what_solvent_and_mixing_name) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.If_yes_what_solvent_and_mixing_ratio) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Time_start) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Time_end) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Temperature_start) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Temperature_end) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Relative_humidity_start) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Relative_humidity_end) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Wind_speed_start) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Wind_speed_end) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Wind_direction_start) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Wind_direction_end) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Spray_direction_start) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Spray_direction_end) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Species) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Hoppers) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Density) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Kuliguli) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Swarm) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Del_Scattered) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Phase) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Spray_platform) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Spray_platform_a) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Spray_platform_g) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Spray_platform_h) + "</b></td>";
//html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Spray_operator) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Name_of_operator) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Spray_manufacturer) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Model_sprayer) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Date_of_last_calibration) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Atomizer_height_above_ground_m) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Coverage_width) + "</b></td>";
//html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Spacing_between_the_sprayer) + "</b></td>"; //Расстояние между проходами опрыскивателя (м)
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Barriers) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Barrier_width) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Spacing_of_barriers_m) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Speed) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Antenna_DGPS_used) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Ground_marking) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Biological_efficiency_of_treatment) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Time_after_treatment_hours) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Efficacy_mortality_method) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Protective_clothing) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Inform_abaut_spraying) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Safety_non_target) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Safety_non_target_effect) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Comments) + "</b></td>";
html += " </tr>\n";
html += " </thead>\n";
html += " <tbody>\n";
int n = 0;
String sql="";
sql+="SELECT\n";
sql+=" fld.id,\n";
sql+=" c.name country_name,\n";
sql+=" cr.name region_name,\n";
sql+=" fld.area,\n"; //Район
sql+=" fld.district,\n"; //Сельский округ и/или хозяйство
sql+=" fld.observer,\n"; //ФИО наблюдателя
sql+=" date(fld.date, 'unixepoch') date,\n"; //Должна быть уникальной
sql+=" fld.terrain,\n"; //Название местности либо урочища
sql+=" fld.lat,\n"; //Широта
sql+=" fld.lon,\n"; //Долгота
sql+=" fld.infested_area,\n"; //заселенная площадь(га)
sql+=" fld.treated_area,\n"; //обработанная площадь(га)
sql+=" fld.vegetation_type,\n"; //Тип(дикая, культурная)
sql+=" fld.vegetation_height,\n"; //Высота (м)
sql+=" fld.vegetation_crop,\n"; //Текстовое поле для перечисления произрастающих культур
sql+=" fld.vegetation_cover,\n"; //Растительный покров (%)
sql+=" fld.vegetation_damage,\n"; //Повреждения растительного покрова(%)
sql+=" fld.vegetation_damage_area,\n"; //Площадь повреждений (га)
sql+=" fld.insecticide_name,\n"; //коммерческое название
sql+=" fld.insecticide_active_substance,\n"; //Наименование активного вещества
sql+=" fld.insecticide_concentration,\n"; //концентрация(г д.в./л или%)
sql+=" fld.insecticide_formulation,\n"; //формуляция(УМО, КЭ, др.)
sql+=" fld.insecticide_dose,\n"; //норма расхода(л/га)
sql+=" fld.insecticide_rate,\n"; //расход рабочей жидкости(л/га)
sql+=" date(fld.insecticide_expiry_date, 'unixepoch') insecticide_expiry_date,\n"; //окончание срока действия
sql+=" CASE fld.insecticide_mixed WHEN 1 THEN 'Yes' WHEN 0 THEN 'No' ELSE '' END insecticide_mixed,\n"; //смешивается ли инсектицид с водой или растворителем?
sql+=" fld.insecticide_mixed_name,\n"; //если да, то с чем
sql+=" fld.insecticide_mixed_ratio,\n"; //если да, то в каком соотношении (%)
sql+=" fld.weather_time_start,\n"; //время начала
sql+=" fld.weather_time_end,\n"; //время окончания
sql+=" fld.weather_temperature_start,\n"; //Температура нач.(°C)
sql+=" fld.weather_temperature_end,\n"; //Температура кон.(°C)
sql+=" fld.weather_humidity_start,\n"; //отн. влажность воздуха нач.(%)
sql+=" fld.weather_humidity_end,\n"; //отн. влажность воздуха кон.(%)
sql+=" fld.weather_wind_speed_start,\n"; //скорость ветра нач. (м/с)
sql+=" fld.weather_wind_speed_end,\n"; //скорость ветра кон. (м/с)
sql+=" ld1.name weather_direction_start,\n"; //направление ветра нач.
sql+=" ld2.name weather_direction_end,\n"; //направление ветра кон.
sql+=" ld3.name weather_spray_direction_start,\n"; //направление опрыскивания нач.
sql+=" ld4.name weather_spray_direction_end,\n"; //направление опрыскивания кон.
sql+=" fld.locust_speciese,\n"; //вид: CIT, DMA, LMI, др.
sql+=" fld.locust_hoppers,\n"; //Стадии личинок
sql+=" fld.locust_density,\n"; //плотность на м2
sql+=" CASE fld.locust_kuliguli WHEN 1 THEN 'Yes' WHEN 0 THEN 'No' ELSE '' END locust_kuliguli,\n"; //Кулиги (да, нет)
sql+=" CASE fld.locust_swarm WHEN 1 THEN 'Yes' WHEN 0 THEN 'No' ELSE '' END locust_swarm,\n"; ////Стаи (да, нет)
sql+=" CASE fld.locust_sparse WHEN 1 THEN 'Yes' WHEN 0 THEN 'No' ELSE '' END locust_sparse,\n"; //Разреженные (да, нет)
sql+=" p.name locust_phase_name,\n"; //Фаза саранчи (одиночная, переходная, стадная)
sql+=" st.name spray_platform,\n"; //Вид опрыскивания
sql+=" sp_a.name spray_platform_a,\n"; //1) «Авиа» - выпадающий список:«Самолет», «Вертолет», «Дельтаплан».
sql+=" sp_g.name spray_platform_g,\n"; //2) «Наземное» - выпадающий список:«Трактор», «Машина», «Аэроз.генераторG».
sql+=" sp_h.name spray_platform_h,\n"; //3) «Ручное» - выпадающий список:«Ранцевый», «Моторный», «Батарейный».
//sql+=" lot.name spray_operatortype_name,\n"; //Оператор (пилот, водитель, др...)
//sql+=" fld.spray_operator_name,\n"; //Имя оператора
sql+=" fld.spray_manufacturer_name,\n"; //Марка опрыскивателя
sql+=" fld.spray_model_name,\n"; //Модель опрыскивателя
//sql+=" date(fld.spray_date_calibration, 'unixepoch') spray_date_calibration,\n"; //Дата последней калибровки
sql+=" fld.spray_height,\n"; //Высота над поверхностью почвы (м)
sql+=" fld.spray_width,\n"; //Ширина захвата (м)
//sql+=" fld.spray_spacing,\n"; //Расстояние между проходами опрыскивателя (м)
sql+=" CASE fld.spray_barrier WHEN 1 THEN 'Yes' WHEN 0 THEN 'No' ELSE '' END spray_barrier,\n"; //Барьеры (да, нет)
sql+=" fld.spray_barrier_width,\n"; //Ширина (м)
sql+=" fld.spray_barrier_space,\n"; //промежуток (м)
sql+=" fld.spray_speed,\n"; //Скорость движения (км/ч)
sql+=" CASE fld.spray_gps WHEN 1 THEN 'Yes' WHEN 0 THEN 'No' ELSE '' END spray_gps,\n"; //Антена: DGPS использовалась
sql+=" fld.spray_marking,\n"; //Наземная маркировка(Сиг-нальщики, GPS, Машина, Нет)
sql+=" fld.efficacy_mortality,\n"; //смертность саранчи(%)
sql+=" fld.efficacy_passed_time,\n"; //Прошло времени после обработки
sql+=" lm.name efficacy_mortality_method,\n"; //метод подсчета смертности
sql+=" CASE fld.safety_clothing WHEN 1 THEN 'Yes' WHEN 0 THEN 'No' ELSE '' END safety_clothing,\n"; //Какой защитной одеждой пользовался оператор (да, нет)
sql+=" fld.safety_inform,\n"; //Кто был оповещен об обработках?
sql+=" CASE fld.safety_non_target WHEN 1 THEN 'Yes' WHEN 0 THEN 'No' ELSE '' END safety_non_target,\n"; //воздействие на нецелевые организмы (да, нет)
sql+=" fld.safety_non_target_effect,\n"; //если да, то какое
sql+=" fld.description\n"; //КОММЕНТАРИИ
sql+="FROM\n";
sql+=" frmlocustdel fld\n";
sql+=" LEFT JOIN countries c ON fld.country_id = c.id\n";
sql+=" LEFT JOIN countriesregions cr ON fld.region_id = cr.id\n";
sql+=" LEFT JOIN list_phase p ON fld.locust_phase_id = p.id\n";
//sql+=" LEFT JOIN list_operatorstypes lot ON lot.id = fld.spray_operatortype_id\n";
sql+=" LEFT JOIN list_directions ld1 ON ld1.id = fld.weather_direction_start\n";
sql+=" LEFT JOIN list_directions ld2 ON ld2.id = fld.weather_direction_end\n";
sql+=" LEFT JOIN list_directions ld3 ON ld3.id = fld.weather_spray_direction_start\n";
sql+=" LEFT JOIN list_directions ld4 ON ld4.id = fld.weather_spray_direction_end\n";
sql+=" LEFT JOIN sprayers_types st ON st.id = fld.spray_platform\n";
sql+=" LEFT JOIN Sprayers sp_a ON sp_a.id = fld.spray_platform_a\n";
sql+=" LEFT JOIN Sprayers sp_g ON sp_g.id = fld.spray_platform_g\n";
sql+=" LEFT JOIN Sprayers sp_h ON sp_h.id = fld.spray_platform_h\n";
sql+=" LEFT JOIN list_mortality lm ON lm.id = fld.efficacy_mortality_method\n";
sql+="where fld.del=0\n";
cursor = dboh.getReadableDatabase().rawQuery(sql, null);
if (cursor.moveToFirst())
{
do
{
n++;
html += " <tr>";
html += "<td>" + n + "</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "country_name") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "region_name") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "area") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "district") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "observer") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "date") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "terrain") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "lat") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "lon") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "infested_area") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "treated_area") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "vegetation_type") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "vegetation_height") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "vegetation_crop") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "vegetation_cover") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "vegetation_damage") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "vegetation_damage_area") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "insecticide_name") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "insecticide_active_substance") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "insecticide_concentration") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "insecticide_formulation") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "insecticide_dose") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "insecticide_rate") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "insecticide_expiry_date") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "insecticide_mixed") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "insecticide_mixed_name") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "insecticide_mixed_ratio") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "weather_time_start") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "weather_time_end") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "weather_temperature_start") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "weather_temperature_end") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "weather_humidity_start") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "weather_humidity_end") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "weather_wind_speed_start") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "weather_wind_speed_end") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "weather_direction_start") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "weather_direction_end") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "weather_spray_direction_start") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "weather_spray_direction_end") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "locust_speciese") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "locust_hoppers") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "locust_density") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "locust_kuliguli") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "locust_swarm") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "locust_sparse") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "locust_phase_name") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "spray_platform") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "spray_platform_a") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "spray_platform_g") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "spray_platform_h") + "&nbsp;</td>";
//html += "<td>" + Tools.getStringFromCursor(cursor, "spray_operatortype_name") + "&nbsp;</td>";
//html += "<td>" + Tools.getStringFromCursor(cursor, "spray_operator_name") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "spray_manufacturer_name") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "spray_model_name") + "&nbsp;</td>";
//html += "<td>" + Tools.getStringFromCursor(cursor, "spray_date_calibration") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "spray_height") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "spray_width") + "&nbsp;</td>";
//html += "<td>" + Tools.getStringFromCursor(cursor, "spray_spacing") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "spray_barrier") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "spray_barrier_width") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "spray_barrier_space") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "spray_speed") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "spray_gps") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "spray_marking") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "efficacy_mortality") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "efficacy_passed_time") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "efficacy_mortality_method") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "safety_clothing") + "&nbsp;</td>";
//html += "<td>" + Tools.getStringFromCursor(cursor, "safety_inform") + "&nbsp;</td>";
html += "<td>";
String dv="";
if(Tools.getStringFromCursor(cursor, "safety_inform").indexOf("1") != -1)
{
html += dv + getString(R.string.Farmer);
dv = ", ";
}
if(Tools.getStringFromCursor(cursor, "safety_inform").indexOf("2") != -1)
{
html += dv + getString(R.string.Villager);
dv = ", ";
}
if(Tools.getStringFromCursor(cursor, "safety_inform").indexOf("3") != -1)
{
html += dv + getString(R.string.Official);
dv = ", ";
}
if(Tools.getStringFromCursor(cursor, "safety_inform").indexOf("4") != -1)
{
html += dv + getString(R.string.Beekeeper);
dv = ", ";
}
if(Tools.getStringFromCursor(cursor, "safety_inform").indexOf("5") != -1)
{
html += dv + getString(R.string.Other);
dv = ", ";
}
html += "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "safety_non_target") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "safety_non_target_effect") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "description") + "&nbsp;</td>";
html += "</tr>\n";
} while (cursor.moveToNext());
}
cursor.close();
dboh.close();
html += " </tbody>\n";
html += " </table>\n";
html += " </body>\n";
html += "</html>\n";
// Сохраняем на карточку
sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
file = new File(Environment.getExternalStorageDirectory() + File.separator + "Data" + File.separator + "Locust" + File.separator
+ "locust_" + sdf.format(new Date()) + ".html");
file.getParentFile().mkdirs();
// создади переменную для записи создания и наполнения файла
FileWriter writer = null;
try
{
writer = new FileWriter(file);
} catch (IOException e)
{
Log.e("Error", "Не создался writer", e);
}
// запишем в файл пару строк
try
{
writer.write(html);
writer.flush();
writer.close();
} catch (IOException e)
{
Log.e("Error", "Не записываются строки", e);
}
//Предлагаем открыть созданый файл
AlertDialog.Builder adb;
adb = new AlertDialog.Builder(this);
adb.setTitle(getString(R.string.Warning)); // заголовок
adb.setMessage(getString(R.string.File_saved_in)+" "+file.getAbsolutePath()); // сообщение
adb.setPositiveButton(getString(R.string.Open), new DialogInterface.OnClickListener() //Кнопка открыть
{
@Override
public void onClick(DialogInterface arg0, int arg1)
{
//Предлагаем открыть созданый файл
if(LocustDelListActivity.this.file.exists())
{
Intent i = new Intent();
i.setAction(android.content.Intent.ACTION_VIEW);
i.setDataAndType(Uri.fromFile(LocustDelListActivity.this.file), "text/html");
startActivity(i);
}
}
});
adb.setNegativeButton(getString(R.string.Cancel), new DialogInterface.OnClickListener() //Кнопка отмена
{
@Override
public void onClick(DialogInterface arg0, int arg1)
{
}
});
AlertDialog ad = adb.show();
ad.getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(Color.BLACK);
ad.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(Color.BLACK);
break;
*/
default:
return false;
}
return true;
}
public void updateList()
{
llList.removeAllViews();
DbOpenHelper dboh = new DbOpenHelper(LocustDelListActivity.this);
Cursor cursor = null;
switch (spiList.getSelectedItemPosition())
{
case 0:
cursor = dboh.getReadableDatabase().rawQuery("select uid, coalesce(district,'') || ' ' || coalesce(terrain,'') terrain, date from frmlocustdel where del=0 and filled!=1", null); //Не отправленные
break;
case 1:
cursor = dboh.getReadableDatabase().rawQuery("select uid, coalesce(district,'') || ' ' || coalesce(terrain,'') terrain, date from frmlocustdel where del=0 and send=0 and filled=1", null); //Не отправленные
break;
case 2:
cursor = dboh.getReadableDatabase().rawQuery("select uid, coalesce(district,'') || ' ' || coalesce(terrain,'') terrain, date from frmlocustdel where del=0 and send=1", null); //Отправленные
break;
default:
cursor = dboh.getReadableDatabase().rawQuery("select uid, coalesce(district,'') || ' ' || coalesce(terrain,'') terrain, date from frmlocustdel where del=0", null); //Все
break;
}
// Tools.logCursor(cursor);
OnClickListener oclBtn = new OnClickListener()
{
@Override
public void onClick(View v)
{
MyButton b = (MyButton) v;
Intent intent = new Intent(LocustDelListActivity.this, LocustDelActivity.class);
intent.putExtra("uid", b.uid);
startActivity(intent);
}
};
if (cursor.moveToFirst())
{
do
{
btn = new MyButton(this);
btn.setOnClickListener(oclBtn);
btn.uid = cursor.getString(cursor.getColumnIndex("uid"));
// Преобразует с учётом временой зоны (пример long dv = 946684800L * 1000L; //2000 ный по гринвичу дало 6 утра)
long dv = cursor.getLong(cursor.getColumnIndex("date")) * (long) 1000;// its need to be in milisecond
Date df = new java.util.Date(dv);
String vv = new SimpleDateFormat("dd.MM.yyyy").format(df);
btn.setText(cursor.getString(cursor.getColumnIndex("terrain")) + " (" + vv + ")");
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
params.bottomMargin = 2;
llList.addView(btn,params);
} while (cursor.moveToNext());
}
cursor.close();
dboh.close();
}
/**
* СМ. http://developer.android.com/reference/android/app/Activity.html Событие происходит при старте и при возврате на этот Activity
* */
@Override
public void onStart()
{
super.onStart();
DbOpenHelper dboh = new DbOpenHelper(this);
SQLiteDatabase db = dboh.getReadableDatabase();
Cursor cursor = db.rawQuery("select * from terminals where del=0 and serial='"+ Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID)+"';", null);
if(!cursor.moveToFirst())
{
Toast toast = Toast.makeText(getApplicationContext(),
getResources().getString(R.string.Please_authorize_the_tablet), Toast.LENGTH_LONG);
toast.show();
}
cursor.close();
dboh.close();
}
}

View File

@ -0,0 +1,668 @@
package kz.istt.locust;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.DatePickerDialog;
import android.app.TimePickerDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.Settings;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.DatePicker;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.Spinner;
import android.widget.TimePicker;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import java.io.File;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Timer;
import java.util.TimerTask;
import dbfields.fieldDB;
public class LocustListActivity extends AppCompatActivity
{
private static final int PERMISSION_REQUEST_CODE_CAMERA = 1;
public LinearLayout llList;
public MyButton btn;
public FloatingActionButton btnAdd = null;
public Spinner spiList = null;
private Timer timer = new Timer();
public File file = null;
//public int g_button=0;
public void alert(String text)
{
AlertDialog.Builder adb = new AlertDialog.Builder(this,R.style.AlertDialogTheme);
adb.setTitle(getString(R.string.Warning));
adb.setMessage(text);
adb.setPositiveButton("OK", new DialogInterface.OnClickListener() //Кнопка открыть
{
@Override
public void onClick(DialogInterface arg0, int arg1)
{}
});
AlertDialog ad = adb.show();
ad.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(Color.BLACK);
}
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_locust_list);
//Загрузка сохранёного языка
Tools.loadLocale(this);
llList = (LinearLayout) findViewById(R.id.llList);
spiList = (Spinner) findViewById(R.id.spiList);
ArrayList<String> list = new ArrayList<String>();
list.add(getString(R.string.Waiting_to_be_filled)); // 0
list.add(getString(R.string.Not_submitted)); // 1
list.add(getString(R.string.Submitted)); // 2
list.add(getString(R.string.All)); // 3
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, list);
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spiList.setAdapter(dataAdapter);
//Событие смены вып списка
spiList.setOnItemSelectedListener(new OnItemSelectedListener()
{
@Override
public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id)
{
//onStart();
updateList();
}
@Override
public void onNothingSelected(AdapterView<?> parentView)
{
}
});
btnAdd = (FloatingActionButton) findViewById(R.id.btnAdd);
btnAdd.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent(LocustListActivity.this, LocustActivity.class);
startActivity(intent);
}
});
//Чтоб список обновлялся раз в минуту в соответствии с текущем фильтром (для наглядности отправки данных)
timer.scheduleAtFixedRate(new TimerTask()
{
@SuppressLint("HandlerLeak")
private Handler myHandle = new Handler() {
@Override
public void handleMessage(Message msg)
{
//onStart();
updateList();
}
};
@Override
public void run() {
myHandle.sendMessage(myHandle.obtainMessage());
}
}, 0, 1000 ); //Раз в минуту
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.locust_list, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
switch (item.getItemId())
{
case R.id.itemCreate: // Создание карточки
//onGetPermissions(1);
Intent intent = new Intent(this, LocustActivity.class);
startActivity(intent);
break;
case R.id.itemDelete: //Удаление всех отправленных из базы
AlertDialog.Builder alertDialog = new AlertDialog.Builder(LocustListActivity.this,R.style.AlertDialogTheme);//new AlertDialog.Builder(this).create();
alertDialog.setCancelable(false);
alertDialog.setTitle(getString(R.string.Warning));
alertDialog.setMessage(getString(R.string.Cleaning));
alertDialog.setPositiveButton(getString(R.string.action_delete), new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int arg1)
{
DbOpenHelper dboh = new DbOpenHelper(LocustListActivity.this);
dboh.getReadableDatabase().execSQL("delete from frmlocust where send=1");
dboh.close();
LocustListActivity.this.onStart();
}
});
alertDialog.setNegativeButton(getString(R.string.Cancel), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int arg1)
{
dialog.cancel();
}
});
AlertDialog ad = alertDialog.show();
ad.getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(Color.BLACK);
ad.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(Color.BLACK);
break;
/* case R.id.itemExport: // Экспорт в Excel всего что накопилось
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss dd.MM.yyyy");
DbOpenHelper dboh = new DbOpenHelper(this);
SQLiteDatabase db = dboh.getReadableDatabase();
String user = "";
Cursor cursor = db.rawQuery("select name,surname,patronymic from _user where del=0;", null);
if (cursor.moveToFirst())
{
user = cursor.getString(cursor.getColumnIndex("surname")) + " " + cursor.getString(cursor.getColumnIndex("name")) + " "
+ cursor.getString(cursor.getColumnIndex("patronymic"));
}
cursor.close();
String html = "";
html += "<html>\n";
html += " <head>\n";
html += " <title>Locust</title>\n";
html += " <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n";
html += " <style>td {mso-number-format: \"\\@\";}</style>";
html += " </head>\n";
html += " <body>\n";
html += "<b>" + getString(R.string.title_activity_locust) + "</b><br>";
html += "<b>" + getString(R.string.Date) + ": </b><i>" + sdf.format(new Date()) + "</i><br>";
html += "<b>" + getString(R.string.User) + ": </b>" + user;
html += " <table border=\"1\" cellspacing=\"0\">\n";
html += " <caption><b>" + getString(R.string.Attributes) + "</b></caption>\n";
html += " <thead>\n";
html += " <tr>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\" style=\"text-align: center\">&nbsp;</td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\" style=\"text-align: center\" colspan=\"4\">&nbsp;</td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\" style=\"text-align: center\" colspan=\"5\"><b>" + getString(R.string.Identification_of_the_place) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\" style=\"text-align: center\" colspan=\"6\"><b>" + getString(R.string.ECOLOGICAL_INFORMATION) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\" style=\"text-align: center\" colspan=\"4\"><b>" + getString(R.string.LOCUST_INFORMATION_INCLUDING_EGG_PODS) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\" style=\"text-align: center\" colspan=\"4\"><b>" + getString(R.string.Eggs) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\" style=\"text-align: center\" colspan=\"5\"><b>" + getString(R.string.Hoppers) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\" style=\"text-align: center\" colspan=\"6\"><b>" + getString(R.string.BANDS) + "</b></td>"; //Кулиги
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\" style=\"text-align: center\" colspan=\"8\"><b>" + getString(R.string.Adults) + "</b></td>"; //Имаго
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\" style=\"text-align: center\" colspan=\"8\"><b>" + getString(R.string.Swarms) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\" style=\"text-align: center\" colspan=\"1\">&nbsp;</td>";
html += " </tr>";
html += " <tr>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>№</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Country) + "</b></td>"; //Страна
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Region) + "</b></td>"; //Область
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Area) + "</b></td>"; //Район
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Rural_district) + "</b></td>"; //Сельский округ и/или хозяйство
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Name_of_survey_team_leader) + "</b></td>"; //Наблюдатель
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Date) + "</b></td>"; //Дата
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Village) + "</b></td>"; //Название местности или урочища
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Lat) + "</b></td>"; //Широта
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Lon) + "</b></td>"; //Долгота
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Surveyed_area_ha) + "</b></td>"; //Обследованная площадь(га)
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Type_of_biotope) + "</b></td>"; //Тип биотопа
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Vegetation) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Vegetation_cover) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Air_temperature) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Wind) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.LOCUST_INFORMATION_INCLUDING_EGG_PODS) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Locust_species) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Area_infested) + "</b></td>"; //Заселённая площадь(га)
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Egg_bed) + "</b></td>"; //Залежь кубышек (площадь м)
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Egg_pods)+ " .. "+ getString(R.string.to) + "</b></td>"; //Кубышки(плотность на м) от/до
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Eggs_number) + "</b></td>"; //Яйца(в среднем в кубышке)
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Eggs_viable) + "</b></td>"; //Яйца(% жизнеспособных)
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Natural_enemies) + "</b></td>"; //Наличие естественных врагов(перечисление)
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Hatching) + "</b></td>"; //Отрождение
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Hopper_stages) + "</b></td>"; //Возраст
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Phase) + "</b></td>"; //Окраска (Фаза)
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Spatial_distribution) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Hopper_density) + " .. " + getString(R.string.to) + "</b></td>";
//Кулиги
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Band_stage) + "</b></td>"; //Возраст
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Band_density) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Band_density_to) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Band_sizes) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Number_of_bands) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Action) + "</b></td>";
//Имаго
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Fledging) + "</b></td>"; //окрыление(%, начало, массовое)
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Maturity) + "</b></td>"; //половозрелость(- или+)
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Phase) + "</b></td>"; //фаза(одиночнаяS, перехoдная Т, стаднаяG)
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Spatial_distribution) + "</b></td>"; //поведение(Изолир., Разреженные, Группы)
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Adult_density) + "</b></td>"; //плотность(на трансекту или га)
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Copulating) + "</b></td>"; //Спаривание (да или нет)
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Laying) + "</b></td>"; //Яйцекладка (да да нет)
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Flying) + "</b></td>"; //полёты(- или+)
//Стаи
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Swarm_maturity) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Density_of_swarm) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Swarm_size) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Number_of_swarms) + "</b></td>"; //Число стай (на га)
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Copulating) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Laying) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Flying_direction) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Flying_height) + "</b></td>";
html += "<td bgcolor=\"#d1d1d1\" width=\"100px\"><b>" + getString(R.string.Comments) + "</b></td>";
html += " </tr>\n";
html += " </thead>\n";
html += " <tbody>\n";
int n = 0;
String sql="";
sql+="SELECT\n";
sql+=" c.name country_name,\n";
sql+=" cr.name region_name,\n";
sql+=" area,\n";
sql+=" district,\n";
sql+=" observer,\n";
sql+=" datetime(date, 'unixepoch') date,\n";
sql+=" terrain,\n";
sql+=" lat,\n";
sql+=" lon,\n";
sql+=" bio_hectare,\n";
sql+=" COALESCE((SELECT translation FROM _translations t JOIN _languages l ON t.language_id=l.id WHERE t.del = 0 AND identifier = lb.name AND l.short_name='"+Tools.getLang()+"' LIMIT 1),lb.name) bio_biotope_name,\n";
sql+=" lgr.name bio_greenery,\n";
sql+=" COALESCE((SELECT translation FROM _translations t JOIN _languages l ON t.language_id=l.id WHERE t.del = 0 AND identifier = lc.name AND l.short_name='"+Tools.getLang()+"' LIMIT 1),lc.name) bio_greenery_cover_name,\n";
sql+=" bio_temperature,\n";
sql+=" bio_wind,\n";
sql+=" CASE locust_have WHEN 1 THEN 'Yes' WHEN 0 THEN 'No' ELSE '' END locust_have,\n";
sql+=" COALESCE((SELECT translation FROM _translations t JOIN _languages l ON t.language_id=l.id WHERE t.del = 0 AND identifier = lt.name AND l.short_name='"+Tools.getLang()+"' LIMIT 1),lt.name) locust_type_name,\n";
sql+=" locust_populated,\n";
sql+=" eggs_capsules_area,\n";
sql+=" eggs_capsules_density,\n";
sql+=" eggs_capsules_density_to,\n";
sql+=" eggs_capsules,\n";
sql+=" eggs_live,\n";
sql+=" eggs_enemies,\n";
sql+=" COALESCE((SELECT translation FROM _translations t JOIN _languages l ON t.language_id=l.id WHERE t.del = 0 AND identifier = b.name AND l.short_name='"+Tools.getLang()+"' LIMIT 1),b.name) larva_born_name,\n";
sql+=" COALESCE((SELECT translation FROM _translations t JOIN _languages l ON t.language_id=l.id WHERE t.del = 0 AND identifier = lag2.name AND l.short_name='"+Tools.getLang()+"' LIMIT 1),lag2.name) larva_age,\n";
sql+=" COALESCE((SELECT translation FROM _translations t JOIN _languages l ON t.language_id=l.id WHERE t.del = 0 AND identifier = lp.name AND l.short_name='"+Tools.getLang()+"' LIMIT 1),lp.name) larva_painting_name,\n";
sql+=" COALESCE((SELECT translation FROM _translations t JOIN _languages l ON t.language_id=l.id WHERE t.del = 0 AND identifier = lbh.name AND l.short_name='"+Tools.getLang()+"' LIMIT 1),lbh.name) larva_behavior_name,\n";
sql+=" larva_density,\n";
sql+=" larva_density_to,\n";
sql+=" COALESCE((SELECT translation FROM _translations t JOIN _languages l ON t.language_id=l.id WHERE t.del = 0 AND identifier = lag.name AND l.short_name='"+Tools.getLang()+"' LIMIT 1),lag.name) kuliguli_age,\n";
sql+=" kuliguli_density,\n";
sql+=" kuliguli_density_to,\n";
sql+=" kuliguli_size,\n";
sql+=" kuliguli_count,\n";
sql+=" COALESCE((SELECT translation FROM _translations t JOIN _languages l ON t.language_id=l.id WHERE t.del = 0 AND identifier = lac.name AND l.short_name='"+Tools.getLang()+"' LIMIT 1),lac.name) kuliguli_action_name,\n";
sql+=" COALESCE((SELECT translation FROM _translations t JOIN _languages l ON t.language_id=l.id WHERE t.del = 0 AND identifier = flg.name AND l.short_name='"+Tools.getLang()+"' LIMIT 1),flg.name) imago_wing_name,\n";
sql+=" CASE imago_maturity WHEN 1 THEN 'Yes' WHEN 0 THEN 'No' ELSE '' END imago_maturity,\n";
sql+=" imago_phase,\n";
sql+=" imago_action,\n";
sql+=" imago_density,\n";
sql+=" CASE imago_copulation WHEN 1 THEN 'Yes' WHEN 0 THEN 'No' ELSE '' END imago_copulation,\n";
sql+=" CASE imago_laying WHEN 1 THEN 'Yes' WHEN 0 THEN 'No' ELSE '' END imago_laying,\n";
sql+=" CASE imago_flying WHEN 1 THEN 'Yes' WHEN 0 THEN 'No' ELSE '' END imago_flying,\n";
sql+=" CASE swarm_maturity WHEN 1 THEN 'Yes' WHEN 0 THEN 'No' ELSE '' END swarm_maturity,\n";
sql+=" COALESCE((SELECT translation FROM _translations t JOIN _languages l ON t.language_id=l.id WHERE t.del = 0 AND identifier = ldy.name AND l.short_name='"+Tools.getLang()+"' LIMIT 1),ldy.name) swarm_density_name,\n";
sql+=" swarm_size,\n";
sql+=" swarm_count,\n";
sql+=" CASE swarm_copulation WHEN 1 THEN 'Yes' WHEN 0 THEN 'No' ELSE '' END swarm_copulation,\n";
sql+=" CASE swarm_laying WHEN 1 THEN 'Yes' WHEN 0 THEN 'No' ELSE '' END swarm_laying,\n";
sql+=" COALESCE((SELECT translation FROM _translations t JOIN _languages l ON t.language_id=l.id WHERE t.del = 0 AND identifier = lds.name AND l.short_name='"+Tools.getLang()+"' LIMIT 1),lds.name) swarm_flying_direction_name,\n";
sql+=" ldy2.name swarm_height,\n";
sql+=" description\n";
sql+="FROM\n";
sql+=" frmlocust fl\n";
sql+=" LEFT JOIN countries c ON fl.country_id = c.id\n";
sql+=" LEFT JOIN countriesregions cr ON fl.region_id = cr.id\n";
sql+=" LEFT JOIN locuststypes lt ON fl.locust_type_id = lt.id\n";
sql+=" LEFT JOIN list_density ldy ON fl.swarm_density_id = ldy.id\n";
sql+=" LEFT JOIN list_directions lds ON fl.swarm_flying_direction_id = lds.id\n";
sql+=" LEFT JOIN list_greenery lgr ON fl.bio_greenery_id = lgr.id\n";
sql+=" LEFT JOIN list_density ldy2 ON ldy2.id=fl.swarm_height_id\n";
sql+=" LEFT JOIN list_age lag ON lag.id = fl.kuliguli_age_id\n";
sql+=" LEFT JOIN list_age lag2 ON lag.id = fl.larva_age_id\n";
sql+=" LEFT JOIN list_biotope lb on lb.id=fl.bio_biotope_id\n";
sql+=" LEFT JOIN list_cover lc on lc.id=fl.bio_greenery_cover_id\n";
sql+=" LEFT JOIN Borns b on b.id=fl.larva_born_id\n";
sql+=" LEFT JOIN list_paintings lp on lp.id=fl.larva_painting_id\n";
sql+=" LEFT JOIN list_behaviors lbh on lbh.id=fl.larva_behavior_id\n";
sql+=" LEFT JOIN list_actions lac on lac.id=fl.kuliguli_action_id\n";
sql+=" LEFT JOIN Fledgling flg on flg.id=fl.imago_wing_id\n";
sql+="where fl.del=0\n";
cursor = dboh.getReadableDatabase().rawQuery(sql, null);
if (cursor.moveToFirst())
{
do
{
n++;
html += " <tr>";
html += "<td>" + n + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "country_name") + "&nbsp;</td>"; //Страна
html += "<td>" + Tools.getStringFromCursor(cursor, "region_name") + "&nbsp;</td>";//Область
html += "<td>" + Tools.getStringFromCursor(cursor, "area") + "&nbsp;</td>"; //Район
html += "<td>" + Tools.getStringFromCursor(cursor, "district") + "&nbsp;</td>"; //Сельский округ и/или хозяйство
html += "<td>" + Tools.getStringFromCursor(cursor, "observer") + "&nbsp;</td>"; //Наблюдатель
html += "<td>" + Tools.getStringFromCursor(cursor, "date") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "terrain") + "&nbsp;</td>"; //Название местности либо урочища
html += "<td>" + Tools.getStringFromCursor(cursor, "lat1") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "lon1") + "&nbsp;</td>";
html += "<td>" + Tools.getStringFromCursor(cursor, "bio_hectare") + "&nbsp;</td>"; //обследованная площадь(га)
html += "<td>" + Tools.getStringFromCursor(cursor, "bio_biotope_name") + "&nbsp;</td>"; //Тип биотопа
html += "<td>" + Tools.getStringFromCursor(cursor, "bio_greenery") + "&nbsp;</td>"; //растительность: сухая, всходы, зеленая, засыхающая
html += "<td>" + Tools.getStringFromCursor(cursor, "bio_greenery_cover_name") + "&nbsp;</td>"; //растительный покров(Редкий, Ср., Густой)
html += "<td>" + Tools.getStringFromCursor(cursor, "bio_temperature") + "&nbsp;</td>"; //погода: температура воздуха(C)
html += "<td>" + Tools.getStringFromCursor(cursor, "bio_wind") + "&nbsp;</td>"; //погода: ветер(м/с)
html += "<td>" + Tools.getStringFromCursor(cursor, "locust_have") + "&nbsp;</td>"; //Присутствует саранча или нет
html += "<td>" + Tools.getStringFromCursor(cursor, "locust_type_name") + "&nbsp;</td>"; //Вид саранчи
html += "<td>" + Tools.getStringFromCursor(cursor, "locust_populated") + "&nbsp;</td>"; //Заселённая площадь(га)
html += "<td>" + Tools.getStringFromCursor(cursor, "eggs_capsules_area") + "&nbsp;</td>"; //залежь кубышек(площадь в м2)
html += "<td>" + Tools.getStringFromCursor(cursor, "eggs_capsules_density")+" .. "+Tools.getStringFromCursor(cursor, "eggs_capsules_density_to") + "&nbsp;</td>"; //кубышки(плотность на м2) от
html += "<td>" + Tools.getStringFromCursor(cursor, "eggs_capsules") + "&nbsp;</td>"; //яйца(в среднем в кубышке)
html += "<td>" + Tools.getStringFromCursor(cursor, "eggs_live") + "&nbsp;</td>"; //яйца(% жизнеспособных)
html += "<td>" + Tools.getStringFromCursor(cursor, "eggs_enemies") + "&nbsp;</td>"; //наличие естественных врагов(каких?)
html += "<td>" + Tools.getStringFromCursor(cursor, "larva_born_name") + "&nbsp;</td>"; //отрождение
html += "<td>" + Tools.getStringFromCursor(cursor, "larva_age") + "&nbsp;</td>"; //возраста: Младшие Средние Старшие
html += "<td>" + Tools.getStringFromCursor(cursor, "larva_painting_name") + "&nbsp;</td>"; //окраска(одиночнаяS, перехoдная Т, стаднаяG)
html += "<td>" + Tools.getStringFromCursor(cursor, "larva_behavior_name") + "&nbsp;</td>"; //поведение(Изолир., Разреженные, Группы)
html += "<td>" + Tools.getStringFromCursor(cursor, "larva_density") + " .. " + Tools.getStringFromCursor(cursor, "larva_density_to") + "&nbsp;</td>"; //плотность на м2 от .. до
html += "<td>" + Tools.getStringFromCursor(cursor, "kuliguli_age") + "&nbsp;</td>"; //cр. возраст(Младшие Средние Старшие)
html += "<td>" + Tools.getStringFromCursor(cursor, "kuliguli_density") + "&nbsp;</td>"; //плотн. в кулиге(на м2)
html += "<td>" + Tools.getStringFromCursor(cursor, "kuliguli_density_to") + "&nbsp;</td>"; //плотн. в кулиге(на м2) до
html += "<td>" + Tools.getStringFromCursor(cursor, "kuliguli_size") + "&nbsp;</td>"; //размер кулиг(м2)
html += "<td>" + Tools.getStringFromCursor(cursor, "kuliguli_count") + "&nbsp;</td>"; //число кулиг
html += "<td>" + Tools.getStringFromCursor(cursor, "kuliguli_action_name") + "&nbsp;</td>"; //поведение: миграция, кормёжка, отдых
html += "<td>" + Tools.getStringFromCursor(cursor, "imago_wing_name") + "&nbsp;</td>"; //окрыление(%, начало, массовое)
html += "<td>" + Tools.getStringFromCursor(cursor, "imago_maturity") + "&nbsp;</td>"; //половозрелость(- или+)
html += "<td>" + Tools.getStringFromCursor(cursor, "imago_phase") + "&nbsp;</td>"; //фаза(одиночнаяS, перехoдная Т, стаднаяG)
html += "<td>" + Tools.getStringFromCursor(cursor, "imago_action") + "&nbsp;</td>"; //поведение(Изолир., Разреженные, Группы)
html += "<td>" + Tools.getStringFromCursor(cursor, "imago_density") + "&nbsp;</td>"; //плотность(на трансекту или га)
html += "<td>" + Tools.getStringFromCursor(cursor, "imago_copulation") + "&nbsp;</td>"; //Спаривание (да или нет)
html += "<td>" + Tools.getStringFromCursor(cursor, "imago_laying") + "&nbsp;</td>"; //Яйцекладка (да да нет)
html += "<td>" + Tools.getStringFromCursor(cursor, "imago_flying") + "&nbsp;</td>"; //полёты(- или+)
//Стаи
html += "<td>" + Tools.getStringFromCursor(cursor, "swarm_maturity") + "&nbsp;</td>"; //половозрелость(- или+)
html += "<td>" + Tools.getStringFromCursor(cursor, "swarm_density_name") + "&nbsp;</td>"; //плотность(на м2)
html += "<td>" + Tools.getStringFromCursor(cursor, "swarm_size") + "&nbsp;</td>"; //размер стаи(на км2)
html += "<td>" + Tools.getStringFromCursor(cursor, "swarm_count") + "&nbsp;</td>"; //число стай
html += "<td>" + Tools.getStringFromCursor(cursor, "swarm_copulation") + "&nbsp;</td>"; //Спаривание (да, нет)
html += "<td>" + Tools.getStringFromCursor(cursor, "swarm_laying") + "&nbsp;</td>"; //Яйцекладка (да, нет)
html += "<td>" + Tools.getStringFromCursor(cursor, "swarm_flying_direction_name") + "&nbsp;</td>"; //направление полёта
html += "<td>" + Tools.getStringFromCursor(cursor, "swarm_height") + "&nbsp;</td>"; //высота(Низкая- Средняя- Высокая)
html += "<td>" + Tools.getStringFromCursor(cursor, "description") + "&nbsp;</td>"; //КОММЕНТАРИИ
html += "</tr>\n";
} while (cursor.moveToNext());
}
cursor.close();
dboh.close();
html += " </tbody>\n";
html += " </table>\n";
html += " </body>\n";
html += "</html>\n";
// Сохраняем на карточку
sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
file = new File(Environment.getExternalStorageDirectory() + File.separator + "Data" + File.separator + "Locust" + File.separator
+ "locust_" + sdf.format(new Date()) + ".html");
file.getParentFile().mkdirs();
// создади переменную для записи создания и наполнения файла
FileWriter writer = null;
try
{
writer = new FileWriter(file);
} catch (IOException e)
{
Log.e("Error", "Не создался writer", e);
}
// запишем в файл пару строк
try
{
writer.write(html);
writer.flush();
writer.close();
} catch (IOException e)
{
Log.e("Error", "Не записываются строки", e);
}
//Предлагаем открыть созданый файл
AlertDialog.Builder adb;
adb = new AlertDialog.Builder(this);
adb.setTitle(getString(R.string.Warning)); // заголовок
adb.setMessage(getString(R.string.File_saved_in)+" "+file.getAbsolutePath()); // сообщение
adb.setPositiveButton(getString(R.string.Open), new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface arg0, int arg1)
{
//Предлагаем открыть созданый файл
Intent i = new Intent();
i.setAction(android.content.Intent.ACTION_VIEW);
i.setDataAndType(Uri.fromFile(LocustListActivity.this.file), "text/html");
startActivity(i);
}
});
adb.setNegativeButton(getString(R.string.Cancel), new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface arg0, int arg1)
{
}
});
AlertDialog ad = adb.show();
ad.getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(Color.BLACK);
ad.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(Color.BLACK);
break;
*/
default:
return false;
}
return true;
}
//Запрашиваю разрешения сдесь хотя GPS на другой форме использую
//WRITE_EXTERNAL_STORAGE
/* public void onGetPermissions(int button)
{
g_button = button;
boolean granted=false;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
List<String> list = new ArrayList<String>();
if (ContextCompat.checkSelfPermission(LocustListActivity.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
list.add(Manifest.permission.CAMERA);
}
if(!list.isEmpty())
{
ActivityCompat.requestPermissions(LocustListActivity.this,list.toArray(new String[list.size()]),PERMISSION_REQUEST_CODE_CAMERA);
granted=false;
}else
{
granted=true;
}
}
if(granted && g_button==1)
{
Intent intent = new Intent(this, LocustActivity.class);
startActivity(intent);
}
if(granted && g_button==2)
{
//ShowLocustDelActivity();
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)
{
if (requestCode == PERMISSION_REQUEST_CODE_CAMERA) {
boolean grant=true;
for(int i=0;i<grantResults.length;i++)
{
grant = grant && grantResults[i] == PackageManager.PERMISSION_GRANTED;
}
if(grant) {
if(g_button==1)
{
Intent intent = new Intent(this, LocustActivity.class);
startActivity(intent);
}
if(g_button==2)
{
//ShowLocustDelActivity();
}
}
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}*/
public void updateList()
{
llList.removeAllViews();
DbOpenHelper dboh = new DbOpenHelper(LocustListActivity.this);
String sql;
Cursor cursor = null;
switch (spiList.getSelectedItemPosition())
{
case 0:
sql = "select uid, coalesce(district,'') || ' ' || coalesce(terrain,'') terrain, date from frmlocust where del=0 and filled!=1";
cursor = dboh.getReadableDatabase().rawQuery(sql, null); //Не заполненые
break;
case 1:
sql = "select uid, coalesce(district,'') || ' ' || coalesce(terrain,'') terrain, date from frmlocust where del=0 and send=0 and filled=1";
cursor = dboh.getReadableDatabase().rawQuery(sql, null); //Не отправленные
break;
case 2:
sql = "select uid, coalesce(district,'') || ' ' || coalesce(terrain,'') terrain, date from frmlocust where del=0 and send=1";
cursor = dboh.getReadableDatabase().rawQuery(sql, null); //Отправленные
break;
default:
sql = "select uid, coalesce(district,'') || ' ' || coalesce(terrain,'') terrain, date from frmlocust where del=0";
cursor = dboh.getReadableDatabase().rawQuery(sql, null); //Все
break;
}
// Tools.logCursor(cursor);
OnClickListener oclBtn = new OnClickListener()
{
@Override
public void onClick(View v)
{
MyButton b = (MyButton) v;
Intent intent = new Intent(LocustListActivity.this, LocustActivity.class);
intent.putExtra("uid", b.uid);
startActivity(intent);
}
};
if (cursor.moveToFirst())
{
do
{
btn = new MyButton(this);
btn.setOnClickListener(oclBtn);
btn.uid = cursor.getString(cursor.getColumnIndex("uid"));
long dv = cursor.getLong(cursor.getColumnIndex("date")) * (long) 1000; // its need to be in milisecond
Date df = new java.util.Date(dv);
String vv = new SimpleDateFormat("dd.MM.yyyy HH:mm").format(df);
btn.setText(cursor.getString(cursor.getColumnIndex("terrain")) + " (" + vv + ")");
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
params.bottomMargin = 2;
llList.addView(btn,params);
} while (cursor.moveToNext());
}
cursor.close();
dboh.close();
}
/**
* СМ. http://developer.android.com/reference/android/app/Activity.html Событие происходит при старте и при возврате на этот Activity
* */
@Override
public void onStart() {
super.onStart();
DbOpenHelper dboh = new DbOpenHelper(this);
SQLiteDatabase db = dboh.getReadableDatabase();
Cursor cursor = db.rawQuery("select * from terminals where del=0 and serial='"+ Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID)+"';", null);
if(!cursor.moveToFirst())
{
Toast toast = Toast.makeText(getApplicationContext(),
getResources().getString(R.string.Please_authorize_the_tablet), Toast.LENGTH_LONG);
toast.show();
}
cursor.close();
dboh.close();
}
}

View File

@ -0,0 +1,396 @@
package kz.istt.locust;
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.provider.Settings.Secure;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import com.google.android.gms.common.GooglePlayServicesNotAvailableException;
import com.google.android.gms.common.GooglePlayServicesRepairableException;
import com.google.android.gms.security.ProviderInstaller;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import javax.net.ssl.SSLContext;
import tctable.Point;
import tctable.TCTable;
public class MainActivity extends Activity {
private Button btnSetup;
private Button btnLocust;
private Button btnLocustDel;
private TextView tvAndroidID;
private TextView tvCountTasks;
private Timer timer = new Timer();
private static final int PERMISSION_REQUEST_CODE = 0;
public int g_button=0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Так как старые планшеты не работают с HTTPS нормально делаем этот патч
try {
// Google Play will install latest OpenSSL
ProviderInstaller.installIfNeeded(getApplicationContext());
SSLContext sslContext;
sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(null, null, null);
sslContext.createSSLEngine();
} catch (GooglePlayServicesRepairableException | GooglePlayServicesNotAvailableException
| NoSuchAlgorithmException | KeyManagementException e) {
e.printStackTrace();
}
//Загрузка сохранёного языка
Tools.loadLocale(this);
DbOpenHelper dboh = new DbOpenHelper(MainActivity.this);;
//Перебираем и удаляем фото файлы названия которых нет в базе данных!
SQLiteDatabase db = dboh.getReadableDatabase();
File directory = new File(Environment.getExternalStorageDirectory() + File.separator + "Pictures" + File.separator + "Locust");
directory.mkdirs();
File[] files = directory.listFiles();
if(files!=null) {
for (int i = 0; i < files.length; i++) {
String fileName = files[i].getName();
if (fileName.charAt(0) == '_')
fileName = fileName.substring(1); //Чтобы не реагировало на "_"
boolean exest = false;
String sql;
Cursor cursor;
sql = "select 1 from frmlocust where image_name1='" + fileName + "' or image_name2='" + fileName + "' or image_name3='" + fileName + "';";
cursor = db.rawQuery(sql, null);
if (cursor.moveToFirst())
exest = exest | true;
cursor.close();
sql = "select 1 from frmlocustdel where image_name1='" + fileName + "' or image_name2='" + fileName + "' or image_name3='" + fileName + "';";
cursor = db.rawQuery(sql, null);
if (cursor.moveToFirst())
exest = exest | true;
cursor.close();
if (!exest) //Если в базе нет удаляем
{
files[i].delete();
}
}
}
//Проверяю есть ли в безе записи и вставляю только если их нет
/* теперь в базу не переписываю так как всё храниться в файлах
boolean exest = false;
String sql = "select 1 from CountriesRegionsPoints limit 1;";
Cursor cursor = db.rawQuery(sql, null);
if (cursor.moveToFirst())
exest = true;
cursor.close();
if(!exest) {
//Переписываю координаты из файла в базу данных
try {
InputStream isRaw = null;
isRaw = getResources().openRawResource(R.raw.points);
if (isRaw != null) {
TCTable tbl = new TCTable("", 0);
if (tbl.OpenTableH(isRaw)) {
dboh.insertTable(tbl);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}*/
db.close();
dboh.close();
tvCountTasks = (TextView) findViewById(R.id.tvCountTasks);
//Запуск службы синхронизации
startService(new Intent(this,MainService.class).putExtra(MainService.PARAM_ACTION, "1"));
//Кнопка вызова формы настроек
btnSetup = (Button) findViewById(R.id.btnSetup);
OnClickListener oclBtnSetup = new OnClickListener(){@Override
public void onClick(View v){ onGetPermissions(3); }};
btnSetup.setOnClickListener(oclBtnSetup);
//Кнопка вызова формы
btnLocust = (Button) findViewById(R.id.btnLocust);
OnClickListener oclBtnLocust = new OnClickListener(){@Override
public void onClick(View v){ onGetPermissions(1); }};
btnLocust.setOnClickListener(oclBtnLocust);
//Кнопка вызова формы
btnLocustDel = (Button) findViewById(R.id.btnLocustDel);
OnClickListener oclBtnLocustDel = new OnClickListener(){@Override
public void onClick(View v){ onGetPermissions(2); }};
btnLocustDel.setOnClickListener(oclBtnLocustDel);
tvAndroidID = (TextView) findViewById(R.id.tvAndroidID);
String android_id = Secure.getString(getContentResolver(), Secure.ANDROID_ID);
tvAndroidID.setText(android_id);
//Версия программы
try {
((TextView) findViewById(R.id.tvVersion)).setText("v "+this.getPackageManager().getPackageInfo(this.getPackageName(), 0).versionName);
} catch (NameNotFoundException e) {
e.printStackTrace();
}
//Для синхронизации справочников
timer.scheduleAtFixedRate(new TimerTask()
{
@SuppressLint("HandlerLeak")
private Handler myHandle = new Handler() {
@Override
public void handleMessage(Message msg)
{
//Если в справочнике нет ни одной записи то перезапускаем синхронизацию (иначе отображаем главное меню)
boolean exists=false;
DbOpenHelper dboh;
Cursor cursor;
dboh = new DbOpenHelper(MainActivity.this);
cursor = dboh.getReadableDatabase().rawQuery("select c.id from borns c limit 1;", null);
if (cursor.moveToFirst())
{
do
{
exists=true;
} while (cursor.moveToNext());
}
cursor.close();
dboh.close();
if(!exists) {
startService(new Intent(MainActivity.this, MainService.class).putExtra(MainService.PARAM_ACTION, "1"));
}else {
LinearLayout pBar = (LinearLayout)findViewById(R.id.pBar);
pBar.setVisibility(View.GONE);
LinearLayout form = (LinearLayout)findViewById(R.id.form);
form.setVisibility(View.VISIBLE);
}
}
};
@Override
public void run() {
myHandle.sendMessage(myHandle.obtainMessage());
}
}, 0, 1000 * 10 * 1 ); //Раз 10 секунд
//Подправлены переводы для грузинского и азербайджанского языка а также изменён размер фотографий на FullHD
}
//Запрашиваю разрешения сдесь хотя GPS на другой форме использую
public void onGetPermissions(int button)
{
g_button = button;
boolean granted=false;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
List<String> list = new ArrayList<String>();
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
list.add(Manifest.permission.ACCESS_COARSE_LOCATION);
}
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
list.add(Manifest.permission.ACCESS_FINE_LOCATION);
}
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
list.add(Manifest.permission.CAMERA);
}
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
list.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
list.add(Manifest.permission.READ_EXTERNAL_STORAGE);
}
if(!list.isEmpty())
{
ActivityCompat.requestPermissions(MainActivity.this,list.toArray(new String[list.size()]),PERMISSION_REQUEST_CODE);
granted=false;
}else
{
granted=true;
}
}else
{
granted=true;
}
if(granted && button==1)
{
ShowLocustActivity();
}
if(granted && button==2)
{
ShowLocustDelActivity();
}
if(granted && button==3)
{
ShowSetupActivity();;
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)
{
if (requestCode == PERMISSION_REQUEST_CODE) {
boolean grant=true;
for(int i=0;i<grantResults.length;i++)
{
grant = grant && grantResults[i] == PackageManager.PERMISSION_GRANTED;
}
if(grant) {
if(g_button==1)
{
ShowLocustActivity();
}
if(g_button==2)
{
ShowLocustDelActivity();
}
if(g_button==3)
{
ShowSetupActivity();
}
}
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void ShowSetupActivity()
{
Intent intent = new Intent(this, SetupActivity.class);
startActivity(intent);
}
public void ShowLocustActivity()
{
//_translations
Intent intent = new Intent(this, LocustListActivity.class);
startActivity(intent);
}
public void ShowLocustDelActivity()
{
//_translations
Intent intent = new Intent(this, LocustDelListActivity.class);
startActivity(intent);
}
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
switch (item.getItemId())
{
case R.id.itemSettings: //Создание карточки
ShowSetupActivity();
break;
default:
return false;
}
return true;
}
/** СМ. http://developer.android.com/reference/android/app/Activity.html
* Происходит при старте и при возврате на этот Activity
* */
@Override
public void onStart()
{
super.onStart();
//Для возможности синхронизации прогресс бара передаём ниточку в поток
PendingIntent pi = createPendingResult(SetupActivity.TASK1_CODE, new Intent(this, MainService.class), 0);
Intent intent = new Intent(this, MainService.class);
intent.putExtra(MainService.PARAM_ACTION, "2");
intent.putExtra(SetupActivity.PARAM_PINTENT, pi);
startService(intent);
}
@Override
protected void onStop() {
super.onStop();
/*
с начала стартует новое окно а потом удаляется старое поэтому без списка не работает
//Удаляем слушателя
Intent intent = new Intent(this, MainService.class);
intent.putExtra(MainService.PARAM_ACTION, "3");
startService(intent);
*/
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
//Пришли данные о статусе синхронизации
if (resultCode == SetupActivity.STATUS_FINISH)
{
int cnt = data.getIntExtra(SetupActivity.PARAM_RESULT, 0);
tvCountTasks.setText("Synchronization tasks: "+ String.valueOf(cnt));
}
}
}

View File

@ -0,0 +1,122 @@
package kz.istt.locust;
import android.annotation.SuppressLint;
//import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.PendingIntent.CanceledException;
import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.util.Log;
import java.util.Timer;
import java.util.TimerTask;
/**
* Служба пытается отправить новые данные каждые 5 мнут на сервере, если нет данных то не отправляет.
* Раз в день должна пытаться обновить пользователя и принять задания.
* @author ivanov.i
*
*/
public class MainService extends Service
{
public final static String PARAM_ACTION = "ACTION";
//NotificationManager m_nm; //http://startandroid.ru/ru/uroki/vse-uroki-spiskom/164-urok-99-service-uvedomlenija-notifications
private Timer timer = new Timer();
private Timer timerP = new Timer(); //Прогрес бар уведомлений
MySynchronizationOld _syn = null;
public PendingIntent m_pi = null; //Слушатель прогрес бара
@Override
public void onCreate()
{
super.onCreate();
Log.e("CCALM", "Servuce id start.");
//m_nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
_syn = new MySynchronizationOld(this);
timer.scheduleAtFixedRate(new TimerTask()
{
@SuppressLint("HandlerLeak")
private Handler myHandle = new Handler() {
@Override
public void handleMessage(Message msg)
{
timerTic(false);
}
};
@Override
public void run() {
myHandle.sendMessage(myHandle.obtainMessage());
}
},0,1000 * 60 * 5 ); //Раз в 5 минут (либо отдельно при сохранении записи)
//Отображаем прогресс бар синхронизации в уведомлениях каждую секунду
timerP.scheduleAtFixedRate(new TimerTask()
{
@Override
public void run()
{
if(MainService.this.m_pi != null)
{
int cnt=_syn.getCount();
Intent intent = new Intent().putExtra(SetupActivity.PARAM_RESULT, cnt);
try
{
m_pi.send(MainService.this, SetupActivity.STATUS_FINISH, intent);
} catch (CanceledException e)
{
e.printStackTrace();
}
}
}
},0,500);
}
@Override
public IBinder onBind(Intent arg0)
{
return null;
}
//Для приёма данных из приложения в сервис
public int onStartCommand(Intent intent, int flags, int startId)
{
if(intent!=null)
{
String act=intent.getStringExtra(MainService.PARAM_ACTION);
if(act!=null)
{
if(act.equals("1"))
{
timerTic(true);
}else
if(act.equals("2")) //Присвоили слушателя прогресс бара
{
m_pi = intent.getParcelableExtra(SetupActivity.PARAM_PINTENT);
}else
if(act.equals("3")) //Очистить слушателя прогрес бара
{
m_pi = null;
}
}
}
return super.onStartCommand(intent, flags, startId);
}
private void timerTic(boolean bAll)
{
Log.e("CCALM", "Start synhronization");
_syn.Synch();
}
}

View File

@ -0,0 +1,310 @@
package kz.istt.locust;
import androidx.core.content.res.ResourcesCompat;
import androidx.fragment.app.FragmentActivity;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Parcelable;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.Polygon;
import com.google.android.gms.maps.model.PolygonOptions;
import com.google.maps.android.PolyUtil;
import com.google.maps.android.SphericalUtil;
import com.google.maps.android.clustering.ClusterManager;
import com.google.maps.android.ui.IconGenerator;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import dbfields.selectDB;
import tctable.Point;
import tools.ClusterMarker;
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, LocationListener, GoogleMap.OnMapLongClickListener {
private GoogleMap mMap=null;
private boolean first=true;
private List<LatLng> places = new ArrayList<>();
private String mapsApiKey;
private int width;
private double _lat = 0; // от устройства
private double _lon = 0; // от устройства
ArrayList<LatLon> points=new ArrayList<LatLon>();
ArrayList<Polygon> polygons=new ArrayList<Polygon>();
Polygon polygon=null;
String uid="";
private Marker marker=null;
private LocationManager lm;
//To use vector image as marker icon need convert him in bitmap
public Bitmap getMarker(int resID) {
IconGenerator iconGen = new IconGenerator(this);
// Define the size you want from dimensions file
int shapeSize = 32;//this.getResources().getDimensionPixelSize(R.dimen.custom_marker_size);
Drawable shapeDrawable = ResourcesCompat.getDrawable(this.getResources(), resID, null);
iconGen.setBackground(shapeDrawable);
// Create a view container to set the size
View view = new View(this);
view.setLayoutParams(new ViewGroup.LayoutParams(shapeSize, shapeSize));
iconGen.setContentView(view);
// Create the bitmap
Bitmap bitmap = iconGen.makeIcon();
return bitmap;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
Intent intent = getIntent();
points = intent.getParcelableArrayListExtra("LatLon");
uid = intent.getStringExtra("uid");
// Чтоб слушать GPS
lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 500, 1, this);
}
/**
* Manipulates the map once available.
* This callback is triggered when the map is ready to be used.
* This is where we can add markers or lines, add listeners or move the camera. In this case,
* we just add a marker near Sydney, Australia.
* If Google Play services is not installed on the device, the user will be prompted to install
* it inside the SupportMapFragment. This method will only be triggered once the user has
* installed Google Play services and returned to the app.
*/
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
mMap.setOnMapLongClickListener(this);
polygons.clear();
// Add a marker in Sydney and move the camera
LatLng center = new LatLng(46.24, 50.30);
marker=mMap.addMarker(new MarkerOptions()
.position(center)
.title("Inspector")
.icon(BitmapDescriptorFactory.fromBitmap(getMarker(R.drawable.ic_inspector)))
);
marker.setVisible(false);
//Геозоны обследования саранчи
DbOpenHelper dboh = new DbOpenHelper(this);
Cursor cursor = dboh.getReadableDatabase().rawQuery("select frmlocust_uid,lat,lon from frmlocust_locations where frmlocust_uid!='"+uid+"' order by frmlocust_uid,pos;", null);
if (cursor.moveToFirst()) {
String uid="";
PolygonOptions pOptions2 = new PolygonOptions();
do {
if(!uid.equals(cursor.getString(0)) && pOptions2.getPoints().size()>1) {
Polygon polygon = mMap.addPolygon(pOptions2);
polygons.add(polygon);
polygon.setFillColor(0x7F0000FF);
}
if(!uid.equals(cursor.getString(0))) {
pOptions2 = new PolygonOptions();
uid=cursor.getString(0);
}
pOptions2.add(new LatLng(cursor.getDouble(1), cursor.getDouble(2)));
} while (cursor.moveToNext());
if(pOptions2.getPoints().size()>1){
Polygon polygon = mMap.addPolygon(pOptions2);
polygons.add(polygon);
polygon.setFillColor(0x7F0000FF);
}
}
cursor.close();
//Геозоны противосаначовой обработки
cursor = dboh.getReadableDatabase().rawQuery("select frmlocustdel_uid,lat,lon from frmlocustdel_locations where frmlocustdel_uid!='"+uid+"' order by frmlocustdel_uid,pos;", null);
if (cursor.moveToFirst()) {
String uid="";
PolygonOptions pOptions2 = new PolygonOptions();
do {
if(!uid.equals(cursor.getString(0)) && pOptions2.getPoints().size()>1) {
Polygon polygon = mMap.addPolygon(pOptions2);
polygons.add(polygon);
polygon.setFillColor(0x7FFF0000);
}
if(!uid.equals(cursor.getString(0))) {
pOptions2 = new PolygonOptions();
uid=cursor.getString(0);
}
pOptions2.add(new LatLng(cursor.getDouble(1), cursor.getDouble(2)));
} while (cursor.moveToNext());
if(pOptions2.getPoints().size()>1){
Polygon polygon = mMap.addPolygon(pOptions2);
polygons.add(polygon);
polygon.setFillColor(0x7FFF0000);
}
}
cursor.close();
dboh.close();
/**/
//Сreating a polygon. (The main polygon at the end since they overlap each)
PolygonOptions pOptions = new PolygonOptions();
for(int i=0;i<points.size();i++){
if(points.get(i)!=null && points.get(i).lon!=0 && points.get(i).lat!=0)
pOptions.add(new LatLng(points.get(i).lat, points.get(i).lon));
}
if(pOptions.getPoints().size()>0) {
Polygon polygon = mMap.addPolygon(pOptions);
polygon.setFillColor(0x7F00FF00);
center = getPolygonCenterPoint(pOptions.getPoints());
//I derive the square of the region
double area=SphericalUtil.computeArea(pOptions.getPoints())/10000.0;
DecimalFormat df = new DecimalFormat("#.###");
IconGenerator iconFactory = new IconGenerator(this);
iconFactory.setColor(Color.CYAN);
addIcon(mMap, iconFactory, df.format(area) + "ha", center);
}
mMap.moveCamera(CameraUpdateFactory.zoomTo( 5.0f ) );
mMap.moveCamera(CameraUpdateFactory.newLatLng(center));
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
}
@Override
public void onLocationChanged(Location location) {
_lat = location.getLatitude(); // от устройства
_lon = location.getLongitude(); // от устройства
if(marker!=null)
{
marker.setPosition(new LatLng(_lat,_lon));
marker.setVisible(true);
if(first) {
mMap.moveCamera(CameraUpdateFactory.newLatLng(marker.getPosition()));
mMap.animateCamera(CameraUpdateFactory.zoomTo(12.0f));
first=false;
}
}
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
//GoogleMap gm;
//gm.setOnMapLongClickListener(this);
@Override
public void onMapLongClick(LatLng point) {
boolean find=false;
if(mMap!=null){
for(int i=0;i<polygons.size();i++){
Polygon polygon=polygons.get(i);
if(PolyUtil.containsLocation(point, polygon.getPoints(), true)){
this.polygon=polygon;
AlertDialog.Builder adb = new AlertDialog.Builder(this,R.style.AlertDialogTheme);
adb.setTitle(getString(R.string.Warning));
adb.setMessage(MapsActivity.this.getResources().getString(R.string.Copy_polygon));
adb.setPositiveButton(MapsActivity.this.getResources().getString(R.string.Yes), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
Intent intent = new Intent();
ArrayList<LatLon> list=new ArrayList<LatLon>();
for(int j=0;j<MapsActivity.this.polygon.getPoints().size()-1;j++){
list.add(new LatLon(MapsActivity.this.polygon.getPoints().get(j).latitude,MapsActivity.this.polygon.getPoints().get(j).longitude));
}
intent.putParcelableArrayListExtra("LatLon", list);
MapsActivity.this.setResult(Activity.RESULT_OK,intent);
MapsActivity.this.finish();
}
});
adb.setNegativeButton(MapsActivity.this.getResources().getString(R.string.No), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
});
AlertDialog ad = adb.show();
ad.getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(Color.BLACK);
ad.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(Color.BLACK);
find=true;
break;
}
}
}
if(!find)
Toast.makeText(MapsActivity.this, MapsActivity.this.getResources().getString(R.string.Not_found), Toast.LENGTH_LONG).show();
}
private LatLng getPolygonCenterPoint(List<LatLng> polygonPointsList){
LatLng centerLatLng = null;
LatLngBounds.Builder builder = new LatLngBounds.Builder();
for(int i = 0 ; i < polygonPointsList.size() ; i++)
{
builder.include(polygonPointsList.get(i));
}
LatLngBounds bounds = builder.build();
centerLatLng = bounds.getCenter();
return centerLatLng;
}
private void addIcon(GoogleMap googleMap, IconGenerator iconFactory, CharSequence text, LatLng position) {
MarkerOptions markerOptions = new MarkerOptions().
icon(BitmapDescriptorFactory.fromBitmap(iconFactory.makeIcon(text))).
position(position).
anchor(iconFactory.getAnchorU(), iconFactory.getAnchorV());
googleMap.addMarker(markerOptions);
}
}

View File

@ -0,0 +1,16 @@
package kz.istt.locust;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class MyBroadReceiv extends BroadcastReceiver {
final String LOG_TAG = "myLogs";
@Override
public void onReceive(Context context, Intent intent)
{
//может и не раскоментивать? context.startService(new Intent(context, MainService.class));
}
}

View File

@ -0,0 +1,14 @@
package kz.istt.locust;
import android.content.Context;
import android.widget.Button;
public class MyButton extends Button
{
public String uid; //Идентификатор записи может быть NULL если она создана на КПК
MyButton(Context context)
{
super(context);
}
}

View File

@ -0,0 +1,545 @@
package kz.istt.locust;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.AsyncTask;
import android.os.Environment;
import android.util.Log;
/*import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.ContentBody;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.CoreProtocolPNames;
import org.apache.http.util.EntityUtils;*/
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.InputSource;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.concurrent.Semaphore;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import tctable.TCTable;
//import org.apache.http.entity.MultipartEntity;
/** Синхронизация данных с сервером
* Нужно сделать глобальным
* */
public class MySynchronizationNew
{
//public static String URL="https://ccalm.org";
//public static String URL="http://192.168.0.89:8080/CCALM";
public static String URL="https://ccalm.org";
private Context m_context=null;
private SendData sd=null;
public MySynchronizationNew(Context context)
{
m_context=context;
}
public void Synch()
{
if(sd!=null && sd.getCount()!=0)
return;
sd=new SendData(m_context);
sd.addTask("frmlocust");
sd.addTask("frmlocustdel");
sd.addTask("borns"); //Справочник отрождение "Начало", "Массовое".
sd.addTask("countries");
sd.addTask("countriesregions");
sd.addTask("locuststypes");
sd.addTask("sprayers");
sd.addTask("sprayers_types");
sd.addTask("fledgling");
sd.addTask("list_density");
sd.addTask("list_phase");
sd.addTask("list_directions"); //Стороны света (направления)
sd.addTask("list_damage"); //Справочник степень повреждения растительного покрова
sd.addTask("list_mortality"); //Справочник степень повреждения растительного покрова
sd.addTask("list_greenery");
sd.addTask("list_biotope");
sd.addTask("list_cover");
sd.addTask("list_age");
sd.addTask("list_actions");
sd.addTask("list_paintings");
sd.addTask("list_behaviors");
sd.addTask("list_breeding");
sd.addTask("list_capacities");
sd.addTask("list_markings");
sd.addTask("list_containers");
sd.addTask("list_vegetation");
sd.addTask("list_formulation");
sd.addTask("list_height");
sd.addTask("list_enemies");
sd.addTask("terminals");
sd.addTask("_languages");
sd.addTask("_translations");
sd.addTask("files");
sd.execute();
}
public int getCount()
{
if(sd!=null)
return sd.getCount();
else
return 0;
}
public class SendData extends AsyncTask<Void, Void, Void>
{
private Context mContext;
//private String mTableName;
private ArrayList<String> mTList = new ArrayList<String>(); //Защищёный список
private Semaphore mSemaphore = null; //Семафор для доступа к списку заданий
public void addTask(String tableName)
{
try
{
mSemaphore.acquire();
mTList.add(tableName);
} catch (InterruptedException e) {
e.printStackTrace();
} finally
{ mSemaphore.release();
}
}
public int getCount()
{
int result=0;
try
{
mSemaphore.acquire();
result=mTList.size();
} catch (InterruptedException e) {
e.printStackTrace();
} finally
{ mSemaphore.release();
}
return result;
}
SendData(Context context)
{
mContext = context;
mSemaphore = new Semaphore(1);
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
//Отправляю файлик на сервер
protected boolean sendFile(String fName)
{
boolean result=false;
/* try
{
HttpClient httpClient = new DefaultHttpClient();
httpClient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
HttpPost httpPost = new HttpPost(MySynchronizationNew.URL+"/get/?fn=6");
File file = new File(fName);
if(file.exists())
{
MultipartEntity mpEntity = new MultipartEntity();
ContentBody cbFile = new FileBody(file, "image/jpeg");
mpEntity.addPart("file", cbFile);
httpPost.setEntity(mpEntity);
}
HttpResponse response = httpClient.execute(httpPost);
if(response != null)
{
StringReader sr = new StringReader(EntityUtils.toString(response.getEntity(),"utf-8"));
InputSource is = new InputSource(sr);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
try
{
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = null;
try
{
doc = builder.parse(is);
Element root = doc.getDocumentElement();
result= XMLTools.getCDATAValue(root).equals("0"); //Признак что успешно отправили на сервер файл
} catch (Exception e)
{
}
} catch (Exception e) {
}
}
} catch (UnsupportedEncodingException e)
{
} catch (ClientProtocolException e)
{
} catch (IOException e)
{
}*/
return result;
}
Document sendXML(String url, String xml)
{
Document doc=null;
/*
HttpClient httpClient = new DefaultHttpClient();
httpClient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
HttpPost httpPost = new HttpPost(url);
httpPost.addHeader("Content-Type", "application/xml");
StringEntity entity = null;
entity = new StringEntity(xml, "UTF-8");
entity.setContentType("application/xml");
httpPost.setEntity(entity);
HttpResponse response=null;
try {
response = httpClient.execute(httpPost);
} catch (IOException e) {
e.printStackTrace();
}
if(response != null)
{
xml="";
try {
xml = EntityUtils.toString(response.getEntity(),"utf-8");
} catch (IOException e) {
e.printStackTrace();
}
StringReader sr = new StringReader(xml);
InputSource is = new InputSource(sr);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = null;
try {
builder = factory.newDocumentBuilder();
doc = builder.parse(is);
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (Exception e)
{
e.printStackTrace();
}
}
*/
return doc;
}
@Override
protected Void doInBackground(Void... params)
{
/*
while(true)
{
String tableName="";
try
{
mSemaphore.acquire();
if(mTList.size()==0) break;
tableName=mTList.get(0);
} catch (InterruptedException e) {
e.printStackTrace();
} finally
{ mSemaphore.release();
}
Log.e("CCALM", "tableName = " + tableName);
DbOpenHelper dboh=null;
try
{
dboh = new DbOpenHelper(mContext);
if(tableName.equals("frmlocust"))
{
//Отправляю файлы на сервер
SQLiteDatabase db = dboh.getReadableDatabase();
Cursor cursor;
//image1
cursor = db.rawQuery("select uid,image_name1 from frmlocust where image_name1 is not null and image_send1=0 and filled=1;", null);
if (cursor.moveToFirst())
{
if(sendFile(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/Locust/" + cursor.getString(cursor.getColumnIndex("image_name1"))))
{
ContentValues cv = new ContentValues();
cv.put("image_send1", 1); //Отмечаем как отправленное
db.beginTransaction(); //Вроде как защита от многопоточности (для сервиса)
try {
db.update("frmlocust", cv, "uid = ?", new String[] { String.valueOf(cursor.getString(cursor.getColumnIndex("uid"))) });
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
}
}
cursor.close();
//image2
cursor = db.rawQuery("select uid,image_name2 from frmlocust where image_name2 is not null and image_send2=0 and filled=1;", null);
if (cursor.moveToFirst())
{
if(sendFile(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/Locust/" + cursor.getString(cursor.getColumnIndex("image_name1"))))
{
ContentValues cv = new ContentValues();
cv.put("image_send1", 1); //Отмечаем как отправленное
db.beginTransaction(); //Вроде как защита от многопоточности (для сервиса)
try {
db.update("frmlocust", cv, "uid = ?", new String[] { String.valueOf(cursor.getString(cursor.getColumnIndex("uid"))) });
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
}
}
cursor.close();
//image3
cursor = db.rawQuery("select uid,image_name3 from frmlocust where image_name3 is not null and image_send3=0 and filled=1;", null);
if (cursor.moveToFirst())
{
if(sendFile(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/Locust/" + cursor.getString(cursor.getColumnIndex("image_name1"))))
{
ContentValues cv = new ContentValues();
cv.put("image_send1", 1); //Отмечаем как отправленное
db.beginTransaction(); //Вроде как защита от многопоточности (для сервиса)
try {
db.update("frmlocust", cv, "uid = ?", new String[] { String.valueOf(cursor.getString(cursor.getColumnIndex("uid"))) });
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
}
}
cursor.close();
//Отправляю данные в виде XML
cursor = db.rawQuery("select * from frmlocust where filled=1 and send=0", null);
if(cursor.moveToFirst())
{
do{
String xml="<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
xml+="<metadata fn=\"4\">";
for(int i=0;i<cursor.getColumnCount();i++)
{
String val=cursor.getString(i);
if(val==null) val="";
xml+=" <"+cursor.getColumnName(i)+"><![CDATA["+val+"]]></"+cursor.getColumnName(i)+">\n";
}
xml+="</metadata>";
Document doc = sendXML(MySynchronizationNew.URL+"/get/",xml);
if(doc!=null)
{
//Incoming XML: <?xml version="1.0" encoding="utf-8"?><metadata fn="4" reqid=""><uid><![CDATA[0a16990f9f82488b8ccf4a4cb6411904]]></uid></metadata>
Element root = doc.getDocumentElement();
String uid= XMLTools.getCDATAValue(XMLTools.findFirstNode(root,"uid"));
if(uid!="" || uid!="null")
{
ContentValues cv = new ContentValues();
cv.put("send", 1); //Отмечаем как отправленное
db.beginTransaction(); //Вроде как защита от многопоточности (для сервиса)
try {
db.update("frmlocust", cv, "uid = ?", new String[] { String.valueOf(uid) });
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
}
}
}while (cursor.moveToNext());
}
cursor.close();
}else if(tableName.equals("frmlocustdel")) {
//Отправляю файлы на сервер
SQLiteDatabase db = dboh.getReadableDatabase();
Cursor cursor;
//image1
cursor = db.rawQuery("select uid,image_name1 from frmlocustdel where image_send1=0 and filled=1;", null);
if (cursor.moveToFirst()) {
if (sendFile(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/Locust/" + cursor.getString(cursor.getColumnIndex("image_name1")))) {
ContentValues cv = new ContentValues();
cv.put("image_send1", 1); //Отмечаем как отправленное
db.beginTransaction(); //Вроде как защита от многопоточности (для сервиса)
try {
db.update("frmlocustdel", cv, "uid = ?", new String[]{String.valueOf(cursor.getString(cursor.getColumnIndex("uid")))});
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
}
}
cursor.close();
//image2
cursor = db.rawQuery("select uid,image_name2 from frmlocustdel where image_send2=0 and filled=1;", null);
if (cursor.moveToFirst()) {
if (sendFile(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/Locust/" + cursor.getString(cursor.getColumnIndex("image_name1")))) {
ContentValues cv = new ContentValues();
cv.put("image_send1", 1); //Отмечаем как отправленное
db.beginTransaction(); //Вроде как защита от многопоточности (для сервиса)
try {
db.update("frmlocustdel", cv, "uid = ?", new String[]{String.valueOf(cursor.getString(cursor.getColumnIndex("uid")))});
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
}
}
cursor.close();
//image3
cursor = db.rawQuery("select uid,image_name3 from frmlocustdel where image_send3=0 and filled=1;", null);
if (cursor.moveToFirst()) {
if (sendFile(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/Locust/" + cursor.getString(cursor.getColumnIndex("image_name1")))) {
ContentValues cv = new ContentValues();
cv.put("image_send1", 1); //Отмечаем как отправленное
db.beginTransaction(); //Вроде как защита от многопоточности (для сервиса)
try {
db.update("frmlocustdel", cv, "uid = ?", new String[]{String.valueOf(cursor.getString(cursor.getColumnIndex("uid")))});
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
}
}
cursor.close();
//Отправляю данные в виде XML
cursor = db.rawQuery("select * from frmlocustdel where filled=1 and send=0", null);
if (cursor.moveToFirst()) {
do {
String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
xml += "<metadata fn=\"5\">";
for (int i = 0; i < cursor.getColumnCount(); i++) {
String val = cursor.getString(i);
if (val == null) val = "";
xml += " <" + cursor.getColumnName(i) + "><![CDATA[" + val + "]]></" + cursor.getColumnName(i) + ">\n";
}
xml += "</metadata>";
Document doc = sendXML(MySynchronizationNew.URL + "/get/", xml);
if (doc != null) {
//Incoming XML: <?xml version="1.0" encoding="utf-8"?><metadata fn="4" reqid=""><uid><![CDATA[0a16990f9f82488b8ccf4a4cb6411904]]></uid></metadata>
Element root = doc.getDocumentElement();
String uid = XMLTools.getCDATAValue(XMLTools.findFirstNode(root, "uid"));
if (uid != "" || uid != "null") {
ContentValues cv = new ContentValues();
cv.put("send", 1); //Отмечаем как отправленное
db.beginTransaction(); //Вроде как защита от многопоточности (для сервиса)
try {
db.update("frmlocustdel", cv, "uid = ?", new String[]{String.valueOf(uid)});
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
}
}
} while (cursor.moveToNext());
}
cursor.close();
}else if(tableName.equals("files"))
{
}else { //Все остальные стравочники
try {
String seq = "0";
SQLiteDatabase db = dboh.getReadableDatabase();
Cursor cursor = db.rawQuery("select max(seq) as seq from " + tableName + ";", null);
if (cursor.moveToFirst()) {
seq = cursor.getString(cursor.getColumnIndex("seq"));
}
if (seq == null) seq = "0";
cursor.close();
//Отправляем данные на сервер
HttpClient httpClient = new DefaultHttpClient();
httpClient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
//String url = MySynchronizationNew.URL + "/get/?fn=1&r=0&n=" + tableName + "&s=" + seq + "&l=1000";
String url = MySynchronizationNew.URL + "/get/?fn=1&r=0&n=" + tableName + "&s=0&l=1000";
HttpPost httpPost = new HttpPost(url);
HttpResponse response = httpClient.execute(httpPost);
if (response != null) {
TCTable tbl = new TCTable("", 0);
if (tbl.OpenTableH(new ByteArrayInputStream(EntityUtils.toByteArray(response.getEntity())))) {
dboh.updateTable(tbl);
}
}else
{
Log.e("CCALM", "Error load table \"" + tableName + "\";");
}
} catch (ClientProtocolException e) {
Log.e("CCALM", "ClientProtocolException = " + e.toString());
} catch (IOException e) {
Log.e("CCALM", "IOException = " + e.toString());
}
}
} finally
{
if(dboh!=null)
dboh.close();
}
//Удаляю после выполнения задания (а то блокировало базу и вылетали ошибки)
try
{
mSemaphore.acquire();
mTList.remove(0);
} catch (InterruptedException e) {
e.printStackTrace();
} finally
{ mSemaphore.release();
}
}
Log.e("CCALM", "END SYNCHONIZATION");
*/
return null;
}
@Override
protected void onPostExecute(Void result)
{
super.onPostExecute(result);
}
@Override
protected void onCancelled()
{
}
}
}

View File

@ -0,0 +1,911 @@
package kz.istt.locust;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
/*import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.ContentBody;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.CoreProtocolPNames;*/
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.Socket;
import java.net.URL;
import java.net.UnknownHostException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Locale;
import java.util.UUID;
import java.util.concurrent.Semaphore;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSocketFactory;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import tctable.TCTable;
//import org.apache.http.entity.MultipartEntity;
/** Синхронизация данных с сервером
* Нужно сделать глобальным
* */
public class MySynchronizationOld
{
public static String URL="https://ccalm.org";
//public static String URL="http://192.168.0.89:8080/CCALM";
private Context _context; //От какого контекста показывать алерты
//private boolean _showAlert; //Показывать ли окно подождите пожалуйста (его нельзя создавать если в сервисе)
//public ProgressDialog dialog;
public MyThread myThread = null;
private int rid_sendFrmLocust = -1; //Для отправки данных
private int rid_sendFrmLocustDel = -1; //Для отправки данных
private int rid_frmlocust = -1; //Для запроса данных
private int rid_frmlocustdel = -1; //Для запроса данных
private int rid_Borns = -1;
private int rid_countries=-1; //Для идентификации прихода данных списка стран
private int rid_CountriesRegions = -1; //Для идентификации прихода данных списка регионов
private int rid__languages = -1;
private int rid__translations = -1;
private int rid_LocustsTypes = -1; //Виды саранчи
private int rid_list_density = -1;
private int rid_list_directions = -1; //Стороны света (направления)
private int rid_list_phase = -1;
private int rid_sprayers = -1;
private int rid_sprayers_types = -1;
private int rid_Fledgling = -1; //Окрыление
private int rid_list_damage = -1;
private int rid_list_mortality = -1; //Метод подсчёта смертности (визуальный либо учётная рамка)
private int rid_list_greenery = -1; //Состояние растительности
private int rid_list_biotope = -1;
private int rid_list_cover = -1;
private int rid_list_age = -1;
private int rid_list_actions = -1;
private int rid_list_paintings = -1;
private int rid_list_behaviors = -1;
private int rid_list_breeding = -1;
//int rid_list_operatorstypes = -1;
private int rid_list_capacities = -1;
private int rid_list_markings = -1;
private int rid_list_containers = -1; //Что сделали с пустыми контейнерами от отравы
private int rid_list_vegetation = -1;
private int rid_list_formulation = -1;
private int rid_list_height = -1;
private int rid_list_enemies = -1;
private int rid_terminals = -1; //На кого зарегистрирован данныей планшет
private int rid_companies = -1;
MySynchronizationOld(Context context)
{
_context = context;
String appPath = _context.getApplicationContext().getFilesDir().getAbsolutePath();
//Thread for downloading from Internet
myThread = new MyThread(this, appPath);
myThread.start(); //Стартуем поток
}
/*public static HttpClient getTestHttpClient() {
try {
SSLContextBuilder builder = new SSLContextBuilder();
builder.loadTrustMaterial(null, new TrustStrategy() {
@Override
public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
return true;
}
});
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(builder.build(), new NoopHostnameVerifier());
CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
return httpclient;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}*/
public int getCount()
{
if(myThread!=null)
return myThread.getCountTasks();
else
return 0;
}
/** Отправить анкету саранчи на сервер по идентификатору либо по времени создания (время должно быть уникальным)
* */
public void sendFrmLocust(String uid)
{
if(uid==null || uid=="") return;
String xml="";
DbOpenHelper dboh = new DbOpenHelper(_context);
Cursor cursor = null;
cursor = dboh.getReadableDatabase().rawQuery("select * from frmlocust where uid=?", new String[] { String.valueOf(uid) });
if(cursor.moveToFirst())
{
do{
//Если задано имя файла то добавляем его в очередь на отправку на сервер
String fname;
fname=cursor.getString(cursor.getColumnIndex("image_name1"));
if(fname!=null && !fname.equals(""))
myThread.addRequest(MySynchronizationOld.URL+"/get/?fn=6", null, Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/Locust/" + fname);
fname = cursor.getString(cursor.getColumnIndex("image_name2"));
if(fname!=null && !fname.equals(""))
myThread.addRequest(MySynchronizationOld.URL+"/get/?fn=6", null, Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/Locust/" + fname);
fname = cursor.getString(cursor.getColumnIndex("image_name3"));
if(fname!=null && !fname.equals(""))
myThread.addRequest(MySynchronizationOld.URL+"/get/?fn=6", null, Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/Locust/" + fname);
xml="<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
xml+="<metadata fn=\"4\">";
for(int i=0;i<cursor.getColumnCount();i++)
{
String val="";
if(!cursor.isNull(i)) {
if (cursor.getType(i) == 2) { //Because cutting double
val = "" + cursor.getDouble(i);
} else {
val = cursor.getString(i);
}
}
xml+=" <"+cursor.getColumnName(i)+"><![CDATA["+val+"]]></"+cursor.getColumnName(i)+">\n";
}
String geom="";
Cursor cursor2 = dboh.getReadableDatabase().rawQuery("select lat,lon from frmlocust_locations where frmlocust_uid=? order by pos", new String[] { String.valueOf(uid) });
if(cursor2.moveToFirst()) {
String first="["+cursor2.getDouble(1)+","+cursor2.getDouble(0)+"]";
do {
geom+="["+cursor2.getDouble(1)+","+cursor2.getDouble(0)+"],";
}while (cursor2.moveToNext());
geom += first;
geom="{\"type\":\"Polygon\",\"coordinates\":[["+geom+"]]}";
}
xml+=" <geom><![CDATA["+geom+"]]></geom>";
cursor2.close();
xml+="</metadata>";
rid_sendFrmLocust = myThread.addRequest(MySynchronizationOld.URL+"/get/", xml, null);
}while (cursor.moveToNext());
}
cursor.close();
dboh.close();
}
/**
* Отправить форму уничтожения саранчи из базы по идентификатору из базы
* @param uid
*/
public void sendFrmLocustDel(String uid)
{
if(uid==null || uid=="") return;
String xml="";
DbOpenHelper dboh = new DbOpenHelper(_context);
Cursor cursor = null;
cursor = dboh.getReadableDatabase().rawQuery("select * from frmlocustdel where uid=?", new String[] { String.valueOf(uid) });
if(cursor.moveToFirst())
{
do{
//Если задано имя файла то добавляем его в очередь на отправку на сервер
String fname;
fname=cursor.getString(cursor.getColumnIndex("image_name1"));
if(fname!=null && !fname.equals(""))
myThread.addRequest(MySynchronizationOld.URL+"/get/?fn=6", null, Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/Locust/" + fname);
fname = cursor.getString(cursor.getColumnIndex("image_name2"));
if(fname!=null && !fname.equals(""))
myThread.addRequest(MySynchronizationOld.URL+"/get/?fn=6", null, Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/Locust/" + fname);
fname = cursor.getString(cursor.getColumnIndex("image_name3"));
if(fname!=null && !fname.equals(""))
myThread.addRequest(MySynchronizationOld.URL+"/get/?fn=6", null, Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/Locust/" + fname);
xml="<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
xml+="<metadata fn=\"5\">";
for(int i=0;i<cursor.getColumnCount();i++)
{
String val="";
if(!cursor.isNull(i)) {
if (cursor.getType(i) == 2) { //Because cutting double
val = "" + cursor.getDouble(i);
} else {
val = cursor.getString(i);
}
}
xml+=" <"+cursor.getColumnName(i)+"><![CDATA["+val+"]]></"+cursor.getColumnName(i)+">\n";
}
String geom="";
Cursor cursor2 = dboh.getReadableDatabase().rawQuery("select lat,lon from frmlocustdel_locations where frmlocustdel_uid=? order by pos", new String[] { String.valueOf(uid) });
if(cursor2.moveToFirst()) {
String first="["+cursor2.getDouble(1)+","+cursor2.getDouble(0)+"]";
do {
geom+="["+cursor2.getDouble(1)+","+cursor2.getDouble(0)+"],";
}while (cursor2.moveToNext());
geom += first;
geom="{\"type\":\"Polygon\",\"coordinates\":[["+geom+"]]}";
}
xml+=" <geom><![CDATA["+geom+"]]></geom>";
cursor2.close();
xml+="</metadata>";
rid_sendFrmLocustDel = myThread.addRequest(MySynchronizationOld.URL+"/get/", xml, null);
}while (cursor.moveToNext());
}
cursor.close();
dboh.close();
}
//Для обновления справочников
int makeRequest(String tableName)
{
String seq="";
DbOpenHelper dboh = new DbOpenHelper(_context);
SQLiteDatabase db = dboh.getReadableDatabase();
Cursor cursor = db.rawQuery("select max(seq) as seq from " + tableName + ";", null);
if (cursor.moveToFirst()) {
seq = cursor.getString(cursor.getColumnIndex("seq"));
}
if (seq == null) seq = "0";
cursor.close();
dboh.close();
return myThread.addRequest(MySynchronizationOld.URL+"/get/?fn=1&r=0&n="+tableName+"&s=" + seq + "&l=1000","", null);
}
/**
* Синхронизовать данные с сервером (добавляет задания в поток)
* Если в задании синхронизации есть хоть 1 задание не должно синхронизироваться
* boolean bAll - Синхронизировать ли всё (задания и пользователи запрашиваются при запуске программы)
*/
public void Synch()
{
if(myThread.getCountTasks()!=0)
return; //Не начинать новую синхронизацию текущая не закончилась (так мы защищаемся от повторной отправки)
String xml="";
//Последовательно отправляю изменёные пользователям записи (send=0 и они заполнены)
DbOpenHelper dboh = new DbOpenHelper(_context);
Cursor cursor = dboh.getReadableDatabase().rawQuery("select uid from frmlocust where send=0 and filled=1", null);
if(cursor.moveToFirst())
{
do{
sendFrmLocust(cursor.getString(cursor.getColumnIndex("uid")));
}while (cursor.moveToNext());
}
cursor.close();
dboh.close();
//Последовательно отправляю изменёные пользователям записи (send=0 и они заполнены)
dboh = new DbOpenHelper(_context);
cursor = dboh.getReadableDatabase().rawQuery("select uid from frmlocustdel where send=0 and filled=1", null);
if(cursor.moveToFirst())
{
do{
sendFrmLocustDel(cursor.getString(cursor.getColumnIndex("uid")));
}while (cursor.moveToNext());
}
cursor.close();
dboh.close();
//Запрос в очередь на получение списка стран, направлений, итд.
rid_LocustsTypes = makeRequest("locuststypes");
rid_sprayers = makeRequest("sprayers");
rid_sprayers_types = makeRequest("sprayers_types");
rid_Fledgling = makeRequest("fledgling");
rid_list_density = makeRequest("list_density");
rid_list_phase = makeRequest("list_phase");
rid_list_directions = makeRequest("list_directions"); //Стороны света (направления)
rid_list_damage = makeRequest("list_damage"); //Справочник степень повреждения растительного покрова
rid_list_mortality = makeRequest("list_mortality"); //Справочник степень повреждения растительного покрова
rid_list_greenery = makeRequest("list_greenery");
rid_list_biotope = makeRequest("list_biotope");
rid_list_cover = makeRequest("list_cover");
rid_list_age = makeRequest("list_age");
rid_list_actions = makeRequest("list_actions");
rid_list_paintings = makeRequest("list_paintings");
rid_list_behaviors = makeRequest("list_behaviors");
rid_list_breeding = makeRequest("list_breeding");
rid_list_capacities = makeRequest("list_capacities");
rid_list_markings = makeRequest("list_markings");
rid_list_containers = makeRequest("list_containers");
rid_list_vegetation = makeRequest("list_vegetation");
rid_list_formulation = makeRequest("list_formulation");
rid_list_height = makeRequest("list_height");
rid_list_enemies = makeRequest("list_enemies");
rid_terminals = makeRequest("terminals");
rid_companies = makeRequest("companies");
rid_countries = makeRequest("countries"); //Если есть хоть 1 запись то считается что справояники хоть 1 раз загрузились
rid_CountriesRegions = makeRequest("countriesregions");
rid__languages = makeRequest("_languages");
rid__translations = makeRequest("_translations");
rid_Borns = makeRequest("borns"); //Справочник отрождение "Начало", "Массовое".
}
//Пришел ответ от HTTP сервера
//Если резутьтат true то сохранено (данные корректны)
//public boolean incomingData(int rid, byte[] data)
public boolean incomingData(int rid, String filePath)
{
/*if (BuildConfig.DEBUG && ( 0 != ( getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE ) )) {
try {
String log=Tools.getStringFromFile(filePath,1024);
Log.e("CCALM", log);
}catch(Exception ex)
{}
}*/
Boolean result=true;
if(filePath==null || filePath.equals("")) return false;
File file=new File(filePath);
if(!file.exists()) return false;
try
{
FileInputStream is=new FileInputStream(file);
DbOpenHelper dbOpenHelper = new DbOpenHelper(_context);
//Пока не однообразно то по идентификаторам определяем что в двоичном формате
if((rid == rid_list_mortality && rid_list_mortality!=-1) || (rid == rid_list_damage && rid_list_damage!=-1) ||
(rid == rid_list_directions && rid_list_directions!=-1) || (rid == rid_Fledgling && rid_Fledgling!=-1) ||
(rid == rid_sprayers && rid_sprayers!=-1) || (rid == rid_sprayers_types && rid_sprayers_types!=-1) ||
(rid == rid_list_phase && rid_list_phase!=-1) || (rid == rid_list_density && rid_list_density!=-1) ||
(rid == rid_Borns && rid_Borns!=-1) || (rid == rid_LocustsTypes && rid_LocustsTypes!=-1) ||
(rid == rid_countries && rid_countries!=-1) || (rid==rid_CountriesRegions && rid_CountriesRegions!=-1) ||
(rid == rid__languages && rid__languages != -1) || (rid == rid__translations && rid__translations != -1) ||
(rid == rid_frmlocust && rid_frmlocust!=-1) || (rid == rid_frmlocustdel && rid_frmlocustdel!=-1) ||
(rid == rid_list_greenery && rid_list_greenery!=-1) || (rid == rid_list_biotope && rid_list_biotope!=-1) ||
(rid == rid_list_cover && rid_list_cover!=-1) || (rid == rid_list_age && rid_list_age!=-1) ||
(rid == rid_list_actions && rid_list_actions!=-1) || (rid == rid_list_paintings && rid_list_paintings!=-1) ||
(rid == rid_list_behaviors && rid_list_behaviors!=-1) ||
(rid == rid_list_breeding && rid_list_breeding!=-1) ||
(rid == rid_list_capacities && rid_list_capacities!=-1) ||
(rid == rid_list_markings && rid_list_markings!=-1) ||
(rid == rid_list_containers && rid_list_containers!=-1) ||
(rid == rid_list_vegetation && rid_list_vegetation!=-1) ||
(rid == rid_list_formulation && rid_list_formulation!=-1) ||
(rid == rid_list_height && rid_list_height!=-1) ||
(rid == rid_list_enemies && rid_list_enemies!=-1) ||
(rid == rid_terminals && rid_terminals!=-1) ||
(rid == rid_companies && rid_companies!=-1)
)
{
TCTable tbl=new TCTable("",0);
if(tbl.OpenTableH(is))
{
result = dbOpenHelper.updateTable(tbl);
}
}else //Данные в виде XML файла
{
//Парсим файл
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = null;
try {
doc = builder.parse(is);
} catch (Exception e) {
is.close();
file.delete();
return false;
}
Element root = doc.getDocumentElement();
String fn=root.getAttribute("fn");
if (fn.equals("-1")) {
String error= XMLTools.getCDATAValue(root);
Log.e("CCALM", "Error = " + error);
//MyAlert("ASDC: Error!",XMLTools.getCDATAValue(root));
} else if (fn.equals("1")) //Пришли данные о пользователе устройства обновим либо добавим
{
} else if (fn.equals("2")) //Пришли данные заданий по сбору инфы о саранче
{
} else if (fn.equals("3")) //Пришли данные заданий по сбору инфы об уничтожении саранчи
{
} else if (fn.equals("4")) //Сохранили данные о саранче на сервере ставим признак отправленности
{
String uid = XMLTools.getCDATAValue(XMLTools.findFirstNode(root, "uid"));
if (uid == "" || uid == "null") uid = null;
Cursor cursor;
DbOpenHelper dboh = new DbOpenHelper(_context);
SQLiteDatabase db = dboh.getReadableDatabase();
ContentValues cv = new ContentValues();
cv.put("send", 1); //Отмечаем как отправленное
//cv.put("changed", 0); //Отмечаем как не измененное
db.beginTransaction(); //Вроде как защита от многопоточности (для сервиса)
try {
db.update("frmlocust", cv, "uid = ?", new String[]{String.valueOf(uid)});
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
//Ищем имя файла по id и удаляем фотографии
cursor = db.rawQuery("select image_name1, image_name2, image_name3 from frmlocust where uid=?;", new String[]{String.valueOf(uid)});
if (cursor.moveToFirst()) {
String path;
File pFile;
path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/Locust/" + cursor.getString(cursor.getColumnIndex("image_name1"));
pFile = new File(path);
if (pFile.exists()) //Переименовываю файл чтобы зановоне отправить при редактировании
{
pFile.renameTo(new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/Locust/_" + cursor.getString(cursor.getColumnIndex("image_name1"))));
}
path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/Locust/" + cursor.getString(cursor.getColumnIndex("image_name2"));
pFile = new File(path);
if (pFile.exists()) //Переименовываю файл чтобы зановоне отправить при редактировании
{
pFile.renameTo(new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/Locust/_" + cursor.getString(cursor.getColumnIndex("image_name2"))));
}
path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/Locust/" + cursor.getString(cursor.getColumnIndex("image_name3"));
pFile = new File(path);
if (pFile.exists()) //Переименовываю файл чтобы зановоне отправить при редактировании
{
pFile.renameTo(new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/Locust/_" + cursor.getString(cursor.getColumnIndex("image_name3"))));
}
}
db.close();
} else if (fn.equals("5")) //Сохранили данные о саранче на сервере ставим признак отправленности
{
String uid = XMLTools.getCDATAValue(XMLTools.findFirstNode(root, "uid"));
if (uid == "" || uid == "null") uid = null;
Cursor cursor;
DbOpenHelper dboh = new DbOpenHelper(_context);
SQLiteDatabase db = dboh.getReadableDatabase();
ContentValues cv = new ContentValues();
cv.put("send", 1); //Отмечаем как отправленное
//cv.put("changed", 0); //Отмечаем как не измененное
db.beginTransaction(); //Вроде как защита от многопоточности (для сервиса)
try {
db.update("frmlocustdel", cv, "uid = ?", new String[]{String.valueOf(uid)});
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
//Ищем имя файла по id и удаляем фотографии
cursor = db.rawQuery("select image_name1, image_name2, image_name3 from frmlocustdel where uid=?;", new String[]{String.valueOf(uid)});
if (cursor.moveToFirst()) {
String path;
File pFile;
path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/Locust/" + cursor.getString(cursor.getColumnIndex("image_name1"));
pFile = new File(path);
if (pFile.exists()) //Переименовываю файл чтобы заново не отправить при редактировании
{
pFile.renameTo(new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/Locust/_" + cursor.getString(cursor.getColumnIndex("image_name1"))));
}
path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/Locust/" + cursor.getString(cursor.getColumnIndex("image_name2"));
pFile = new File(path);
if (pFile.exists()) //Переименовываю файл чтобы заново не отправить при редактировании
{
pFile.renameTo(new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/Locust/_" + cursor.getString(cursor.getColumnIndex("image_name2"))));
}
path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/Locust/" + cursor.getString(cursor.getColumnIndex("image_name3"));
pFile = new File(path);
if (pFile.exists()) //Переименовываю файл чтобы заново не отправить при редактировании
{
pFile.renameTo(new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/Locust/_" + cursor.getString(cursor.getColumnIndex("image_name3"))));
}
}
db.close();
} else if (fn.equals("6")) //Фото отправлено
{
}
} catch (Exception e) {
//throw new RuntimeException(e);
//MyAlert("ASDC: Synchronization error", e.toString());
//Toast.makeText(this, "MyAlarmService.onDestroy()", Toast.LENGTH_LONG).show();
}
//if(_showAlert) dialog.dismiss();
}
is.close();
file.delete();
} catch (Exception e) {
result = false;
}
return result;
}
}
/* Поток заданий на отправку данных на сервер */
class MyThread extends Thread
{
private int rid = 0; //Инкреминтальный номер ответа для сохранения уникальных файлов
class Tsk //Задание отправки данных
{
String url = ""; //URL куда отправлять данные
String str = ""; //Отправляемая строка
String file = ""; //Отправляемый файл
Boolean s = false; //Integer s = 0; // false - не отправлялось true - в процессе отправки (если ошибка то ставиться статус не отправлено иначе удаляется из списка заданий)
int id = 0; //Инкриментальный идентификатор запроса
int wait = 10; //Милисекунд ждать перед отправкой текущего задания
int t=0; //Количество совершенных попыток отправки
}
private int mId=0; //Инкриментальный идентификатор запроса
private Semaphore mSemaphore = null; //Семафор для доступа к списку заданий
private ArrayList<Tsk> mTList = new ArrayList<Tsk>(); //Защищёный список
private MySynchronizationOld mListener = null; //Для отправки ответов в основной поток
private String mAppPath = "";
//@SuppressLint("HandlerLeak") //Подавить предупреждения о неоптимальности
private Handler myHandle = new Handler() //Для ловли сообщений из другого потока
{
@Override
public void handleMessage(Message msg) //Слушатель ответа после отправки данных на сервер
{
int rid = msg.getData().getInt("id");
//Boolean b = mListener.incomingData(rid, msg.getData().getByteArray("data")); //Слушатель должен вернуть true иниче запрос останется в очереди
Boolean b = mListener.incomingData(rid, msg.getData().getString("file")); //Слушатель должен вернуть true иниче запрос останется в очереди
try
{
mSemaphore.acquire();
for(int i=0; i<mTList.size();i++)
{
if(mTList.get(i).id==rid)
{
if(b) //Удаляем обработанное заданин по id
{ mTList.remove(i);
break;
}else //Не обработаное пытаемся отправить заново (но увеличив ожидание перед повтором прохода заданий на 5 минут но не больше чем раз в 30 минут)
{
mTList.get(i).wait += 1000 * 60 * 5; //Увеличиваем ожидание перед новой отправкой на 5 минут
if(mTList.get(i).wait > 1000 * 60 * 30 ) mTList.get(i).wait = 1000 * 60 * 30; //Ограничение 30 минут
mTList.get(i).s = false; //Отмечаем как не отправленное
mTList.get(i).t++; //Увиличиваем счётчик количество попыток отправки
if(mTList.get(i).t>10) mTList.remove(i); //Удаляем задание после 10 попыток отправки
break;
}
}
}
} catch (InterruptedException ex)
{
} finally
{ mSemaphore.release();
}
}
};
public MyThread(MySynchronizationOld listener, String appPath)
{
mListener = listener;
mAppPath = appPath;
assert(mListener != null);
mSemaphore = new Semaphore(1);
}
// Добавление в задание на отправку до того как не получен ответ от предедущего запроса следующий не отсылается те. последовательно это делает (обработка результатов не в потоке загрузки а в основном потоке)
//return id запроса
public int addRequest(String url, String str, String file)
{
mId++; //Инкрементируем идентификатор запроса
try
{
mSemaphore.acquire();
Tsk t = new Tsk();
t.url = url;
t.str = str;
t.file = file;
t.s = false;
t.id = mId;
mTList.add(t);
} catch (InterruptedException ex)
{
} finally
{ mSemaphore.release();
}
return mId;
}
/**
* Получить количество заданий ожидающих выполнение
* @return
*/
public int getCountTasks()
{
int result=0;
try
{
mSemaphore.acquire();
result = mTList.size();
} catch (InterruptedException ex)
{
} finally
{ mSemaphore.release();
}
return result;
}
@Override
public void run()
{
Tsk tsk;
while(true)
{
//Считываем первое задание из защищёного семафором списка
tsk = null;
try {
mSemaphore.acquire();
for(int i=0;i<mTList.size();i++)
{
if(! mTList.get(i).s)
{ tsk = mTList.get(i);
break;
}
}
} catch (InterruptedException ex) {
// вот такое может произойти, если поток например прервут thread.interrupt()
} finally {
mSemaphore.release(); //Отдаем семафор
}
//Выполняем задание на отправку/приём данных
if(tsk != null)
{
boolean bError=false;
tsk.s = true; //Признак отправляемости запроса на сервер
try {
sleep(tsk.wait); //Если в задании задано сколько подождать перед запуском
} catch (InterruptedException e) { }
try
{
URL url = new URL(tsk.url);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(15000);
conn.setConnectTimeout(15000);
conn.setRequestMethod("POST");
conn.setDoInput(true);
conn.setDoOutput(true);
if(tsk.file!=null) { //Отправляем файл на сервер
File file = new File(tsk.file);
if(file.exists())
{
String boundary = UUID.randomUUID().toString();
String crlf = "\r\n";
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("Cache-Control", "no-cache");
conn.setRequestProperty("Content-Type","multipart/form-data; boundary=" + boundary);
//Так теперь сами данные обрамлённые границей
DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
dos.writeBytes("--"+boundary + crlf);
dos.writeBytes("Content-Type: image/jpeg" + crlf);
dos.writeBytes("Content-Disposition: form-data; name=\"file\";filename=\"" + tctable.Tools.afterLast(tsk.file,"/") + "\"" + crlf);
dos.writeBytes(crlf);
// Read file
byte[] buffer = new byte[1024];
FileInputStream fileInputStream = new FileInputStream(file);
int bytesRead = fileInputStream.read(buffer);
try {
while (bytesRead > 0) {
try {
dos.write(buffer, 0, bytesRead);
} catch (OutOfMemoryError e) {
e.printStackTrace();
}
bytesRead = fileInputStream.read(buffer);
}
} catch (Exception e) {
e.printStackTrace();
}
fileInputStream.close();
dos.writeBytes(crlf);
dos.writeBytes("--"+boundary + "--" + crlf);
dos.flush();
dos.close();
}
}else{
conn.setRequestProperty("Accept-Charset", "UTF-8");
conn.setRequestProperty("Content-Type", "application/xml; charset=utf-8");
conn.setRequestProperty("Accept", "application/xml");
OutputStream os = conn.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
writer.write(tsk.str);
writer.flush();
writer.close();
os.close();
}
int responseCode=conn.getResponseCode();
if (responseCode == HttpsURLConnection.HTTP_OK) {
rid++;
String filePath = mAppPath+"/"+"data_"+ String.valueOf(rid)+".txt";
//Так как файл может быть большим и он может не поместиться в памяти то сохраняем его на диск (допустим таблица с языками очень большая)
try {
BufferedInputStream bis = new BufferedInputStream(conn.getInputStream());
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File(filePath)));
int inByte;
while ((inByte = bis.read()) != -1) bos.write(inByte);
bis.close();
bos.close();
}catch(Exception ex)
{}
//Информирую слушателя о приёме данных
Message msg = myHandle.obtainMessage();
Bundle b = new Bundle();
b.putString("file", filePath);
b.putInt("id", tsk.id);
msg.setData(b);
myHandle.sendMessage(msg);
}
} catch (Exception ex) {
bError = true;
Log.i("igor", ex.toString());
}
/*
HttpClient httpClient = new DefaultHttpClient();
httpClient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
HttpPost httpPost = new HttpPost(tsk.url);
if(tsk.file!=null) //Отправляем файл на сервер
{
File file = new File(tsk.file);
if(file.exists())
{
MultipartEntity mpEntity = new MultipartEntity();
ContentBody cbFile = new FileBody(file, "image/jpeg");
mpEntity.addPart("file", cbFile);
httpPost.setEntity(mpEntity);
}
}else //Отправляем XML строку
{
httpPost.addHeader("Content-Type", "application/xml");
StringEntity entity = new StringEntity(tsk.str, "UTF-8");
entity.setContentType("application/xml");
httpPost.setEntity(entity);
}
HttpResponse response = httpClient.execute(httpPost);
if(response != null)
{
rid++;
String filePath = mAppPath+"/"+"data_"+ String.valueOf(rid)+".txt";
//Так как файл может быть большим и он может не поместиться в памяти то сохраняем его на диск
try {
BufferedInputStream bis = new BufferedInputStream(response.getEntity().getContent());
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File(filePath)));
int inByte;
while ((inByte = bis.read()) != -1) bos.write(inByte);
bis.close();
bos.close();
}catch(Exception ex)
{}
Message msg = myHandle.obtainMessage();
Bundle b = new Bundle();
b.putString("file", filePath);
b.putInt("id", tsk.id);
msg.setData(b);
myHandle.sendMessage(msg);
}else
bError = true; //Если ошибка при принятии ответа
} catch (UnsupportedEncodingException ex)
{
bError = true;
Log.i("igor", "Error 5 = " + ex.toString());
} catch (ClientProtocolException ex)
{
bError = true;
Log.i("igor", "Error 6 = " + ex.toString());
} catch (IOException ex)
{
bError = true;
Log.i("igor", "Error 7 = " + ex.toString());
}
*/
if(bError) //Если произошла ошибка при отправке.
{
tsk.wait += 1000 * 60 * 1; //Увеличиваем ожидание перед новой отправкой на 1 минуту
if(tsk.wait > 1000 * 60 * 10 ) tsk.wait = 1000 * 60 * 10; //Ограничение 10 минут
tsk.s = false; //Отмечаем как не отправленное
tsk.t++; //Увеличиваем счётчик количество попыток отправки
if(tsk.t>10) //Удаляем задание после 10 попыток отправки
{
try {
mSemaphore.acquire();
mTList.remove(tsk);
} catch (InterruptedException ex)
{
// вот такое может произойти, если поток например прервут thread.interrupt()
} finally
{
mSemaphore.release(); //Отдаем семафор
}
}
}
}
try {
sleep(100); //Задержка между каждым выполнением задания
} catch (InterruptedException e) { }
}
}
}

View File

@ -0,0 +1,500 @@
package kz.istt.locust;
import static kz.istt.locust.Tools.md5;
import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteStatement;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.provider.Settings;
import android.util.SparseArray;
import android.view.Display;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.Space;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import com.google.android.gms.vision.CameraSource;
import com.google.android.gms.vision.Detector;
import com.google.android.gms.vision.Frame;
import com.google.android.gms.vision.barcode.Barcode;
import com.google.android.gms.vision.barcode.BarcodeDetector;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import javax.net.ssl.HttpsURLConnection;
public class ScanActivity extends Activity {
public static final int PICK_IMAGE = 1;
final Handler mHandler = new Handler();
public ProgressDialog mPd=null;
public SurfaceView surfaceView;
//public SurfaceView svDrawingFrame;
//public TextView txtBarcodeValue;
private Detector barcodeDetector=null;
private CameraSource cameraSource;
private static final int REQUEST_CAMERA_PERMISSION = 201;
public FloatingActionButton btnOpen = null;
public String intentData = "";
public boolean isEmail = false;
public String qrcode = "";
public TextView tvName = null;
public TextView tvCountry = null;
public TextView tvOrganization = null;
public void showProgress(boolean show,String title)
{
if(mPd==null && show) {
mPd = new ProgressDialog(this);
mPd.setTitle(title);
mPd.setMessage(getResources().getString(R.string.Wait_please));
mPd.setCanceledOnTouchOutside(false);
mPd.setCancelable(false);
mPd.setIndeterminate(true);
mPd.show();
}
if(mPd!=null && !show) {
mPd.hide();
mPd=null;
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scan);
//txtBarcodeValue = findViewById(R.id.txtBarcodeValue);
surfaceView = findViewById(R.id.surfaceView);
tvName = (TextView) findViewById(R.id.tvName);
tvCountry = (TextView) findViewById(R.id.tvCountry);
tvOrganization = (TextView) findViewById(R.id.tvOrganization);
DbOpenHelper dboh = new DbOpenHelper(this);
SQLiteDatabase db = dboh.getReadableDatabase();
Cursor cursor = db.rawQuery("select " +
" cr.name as country_name," +
" cp.name as company_name," +
" t.name " +
"from " +
" terminals t " +
" left join countries cr on cr.id=t.country_id " +
" left join companies cp on cp.id=t.company_id " +
"where t.del=0 and t.serial='"+Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID)+"';", null);
if(cursor.moveToFirst())
{
tvCountry.setText(cursor.getString(cursor.getColumnIndex("country_name")));
tvOrganization.setText(cursor.getString(cursor.getColumnIndex("company_name")));
tvName.setText(cursor.getString(cursor.getColumnIndex("name")));
}
cursor.close();
dboh.close();
//surfaceView.setZOrderOnTop(false); //CODE TO SET VIDEO VIEW TO BACK
//svDrawingFrame = findViewById(R.id.svDrawingFrame);
//svDrawingFrame.setZOrderOnTop(true);
/*btnAction = findViewById(R.id.btnAction);
btnAction.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (intentData.length() > 0) {
if (isEmail) {
//startActivity(new Intent(ScanActivity.this, EmailActivity.class).putExtra("email_address", intentData));
}else {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(intentData)));
}
}
}
});*/
btnOpen = (FloatingActionButton) findViewById(R.id.btnOpen);
btnOpen.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE);
}
});
//Если QR не работает то и не отображаю кнопки
BarcodeDetector bDetector = new BarcodeDetector.Builder(ScanActivity.this)
.setBarcodeFormats(Barcode.QR_CODE) // set QR code as the format type
.build();
if(!bDetector.isOperational()) {
btnOpen.setVisibility(View.GONE);
surfaceView.setVisibility(View.GONE);
}else{
((TextView) findViewById(R.id.tvUpdate)).setVisibility(View.GONE);
((Space) findViewById(R.id.sUpdate)).setVisibility(View.GONE);
}
bDetector.release();
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_IMAGE) {
if (data == null) {
return;
}
InputStream inputStream = null;
try {
inputStream = getContentResolver().openInputStream(data.getData());
} catch (FileNotFoundException e) {
e.printStackTrace();
}
if (inputStream != null) {
BarcodeDetector bDetector = new BarcodeDetector.Builder(ScanActivity.this)
.setBarcodeFormats(Barcode.QR_CODE) // set QR code as the format type
.build();
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
Frame frame = new Frame.Builder().setBitmap(bitmap).build();
if (bDetector.isOperational()) {
final SparseArray<Barcode> barcodes = bDetector.detect(frame);
if (barcodes.size() == 0) {
Toast toast = Toast.makeText(getApplicationContext(),
getResources().getString(R.string.QR_code_not_found), Toast.LENGTH_LONG);
toast.show();
} else {
qrcode = barcodes.valueAt(0).displayValue;
if(qrcode.indexOf("ccalm")>=0){
String android_id = Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID);
DataActSendTask send = new DataActSendTask(qrcode,android_id);
send.execute();
}else{
Toast toast = Toast.makeText(getApplicationContext(),
getResources().getString(R.string.Error_QR_code)+": \""+qrcode+"\"", Toast.LENGTH_LONG);
toast.show();
}
}
}
bDetector.release();
}
}
}
public void setJSONObject(JSONObject json)
{
try {
if(json.getInt("errorCode")==0) {
tvName.setText(json.getString("name"));
tvCountry.setText(json.getString("country_name"));
tvOrganization.setText(json.getString("company_name"));
//Update terminals table (After that, the terminal tables will be updated using synchronization.)
String sql="select * from terminals where id="+json.getString("id");
boolean exists=false;
DbOpenHelper dboh = new DbOpenHelper(this);
SQLiteDatabase db = dboh.getReadableDatabase();
Cursor cursor = db.rawQuery(sql, null);
if(cursor.moveToFirst())
{
exists=true;
}
cursor.close();
if(exists){
sql="update terminals set country_id=?,company_id=?,name=?,serial=? where id=?";
SQLiteDatabase wdb = dboh.getWritableDatabase();
SQLiteStatement stmt = wdb.compileStatement(sql);
stmt.bindLong(1, json.getLong("country_id"));
stmt.bindLong(2, json.getLong("company_id"));
stmt.bindString(3, json.getString("name"));
stmt.bindString(4, Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID));
stmt.bindLong(5, json.getLong("id"));
stmt.executeUpdateDelete();
}else{
sql="insert into terminals(id,country_id,company_id,name,serial)values(?,?,?,?,?);";
SQLiteDatabase wdb = dboh.getWritableDatabase();
SQLiteStatement stmt = wdb.compileStatement(sql);
stmt.bindLong(1, json.getLong("id"));
stmt.bindLong(2, json.getLong("country_id"));
stmt.bindLong(3, json.getLong("company_id"));
stmt.bindString(4, json.getString("name"));
stmt.bindString(5, Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID));
stmt.executeInsert();
}
dboh.close();
}else {
String errorMessage = json.getString("errorMessage");
if (!errorMessage.equals("")) {
AlertDialog alertDialog = new AlertDialog.Builder(ScanActivity.this).create();
alertDialog.setTitle(getResources().getString(R.string.Attention));
alertDialog.setMessage(errorMessage);
alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
}
});
//alertDialog.setIcon(R.drawable.icon);
alertDialog.show();
}
qrcode = "";
}
} catch (JSONException e) {
e.printStackTrace();
}
}
private void initialiseDetectorsAndSources() {
//Toast.makeText(getApplicationContext(), "Barcode scanner started", Toast.LENGTH_SHORT).show();
barcodeDetector = new BarcodeDetector.Builder(this)
.setBarcodeFormats(Barcode.QR_CODE)
.build();
cameraSource = new CameraSource.Builder(this, barcodeDetector)
.setRequestedPreviewSize(800, 800)
.setAutoFocusEnabled(true) //you should add this feature
.build();
surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {
try {
if (ActivityCompat.checkSelfPermission(ScanActivity.this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
cameraSource.start(surfaceView.getHolder());
} else {
ActivityCompat.requestPermissions(ScanActivity.this, new
String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION);
}
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
cameraSource.stop();
}
});
barcodeDetector.setProcessor(new Detector.Processor<Barcode>() {
/* private final Handler handler = null;
public Detector.Processor<Barcode>() {
handler = new Handler();
}
*/
@Override
public void release() {
//Toast.makeText(getApplicationContext(), "Для предотвращения утечки памяти сканер штрих-кода остановлен", Toast.LENGTH_SHORT).show();
}
@Override
public void receiveDetections(Detector.Detections<Barcode> detections) {
final SparseArray<Barcode> barcodes = detections.getDetectedItems();
if (barcodes.size() != 0) {
mHandler.post(new Runnable() {
@Override
public void run() {
if(!qrcode.equals(barcodes.valueAt(0).displayValue)) {
qrcode = barcodes.valueAt(0).displayValue;
if(qrcode.indexOf("ccalm")>=0){
String android_id = Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID);
DataActSendTask send = new DataActSendTask(qrcode,android_id);
send.execute();
}else{
Toast toast = Toast.makeText(getApplicationContext(),
getResources().getString(R.string.Error_QR_code)+": \""+qrcode+"\"", Toast.LENGTH_LONG);
toast.show();
}
}
}
});
}
}
});
}
@Override
protected void onPause() {
super.onPause();
cameraSource.release();
}
@Override
protected void onResume() {
super.onResume();
initialiseDetectorsAndSources();
//Подгоняем размер под квадран
ViewGroup.LayoutParams params = surfaceView.getLayoutParams();
params.height = getWindowManager().getDefaultDisplay().getWidth();
surfaceView.setLayoutParams(params);
}
//Запрашиваю данные с сервера
public class DataActSendTask extends AsyncTask<Void, Void, Void> {
private final String mQRCode;
private final String mAndroid_id;
private String mErrmsg;
private JSONObject mResult; //Результирующий JSONObject
// mainObject = new JSONObject(Your_Sring_data);
DataActSendTask(String qrcode,String android_id) {
mQRCode=qrcode;
mAndroid_id = android_id;
mErrmsg = "";
mResult = null;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
ScanActivity.this.showProgress(true,getResources().getString(R.string.Search));
}
@Override
protected Void doInBackground(Void... params) {
//I'm trying to login using JSON string
JSONObject data = new JSONObject();
try {
data.put("qrcode",mQRCode);
data.put("android_id",mAndroid_id);
data.put("secret",md5(mAndroid_id+"_ASDC"));
} catch (JSONException ex) {
ex.printStackTrace();
mErrmsg+=ex.getLocalizedMessage()+" ";
}
//Trying to send a request to the server
try {
URL url = new URL(MySynchronizationOld.URL+"/asdc/qrcode/");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(25000);
conn.setConnectTimeout(25000);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json; charset=utf-8");
conn.setRequestProperty("Accept", "application/json");
conn.setRequestProperty("Accept-Charset", "UTF-8");
conn.setDoInput(true);
conn.setDoOutput(true);
OutputStream os = conn.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
writer.write(data.toString());
writer.flush();
writer.close();
os.close();
int responseCode=conn.getResponseCode();
if (responseCode == HttpsURLConnection.HTTP_OK) {
String JSONStr=""; //Результирующий JSON
String line;
BufferedReader br=new BufferedReader(new InputStreamReader(conn.getInputStream()));
while ((line=br.readLine()) != null) {
JSONStr+=line;
}
try {
mResult = new JSONObject(JSONStr);
} catch (JSONException e) {
mErrmsg = "JSON parsing error: "+JSONStr;
}
}else{
mErrmsg = "Failed to get data from the server.";
}
} catch (UnsupportedEncodingException e) {
mErrmsg = e.getMessage();
} catch (IOException e) {
mErrmsg = e.getMessage();
}
return null;
}
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
ScanActivity.this.showProgress(false,"");
if (mResult != null)
ScanActivity.this.setJSONObject(mResult);
if (mErrmsg != null && !mErrmsg.equals("")) {
AlertDialog alertDialog = new AlertDialog.Builder(ScanActivity.this).create();
alertDialog.setTitle("Error");
alertDialog.setMessage(mErrmsg);
alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
}
});
//alertDialog.setIcon(R.drawable.icon);
alertDialog.show();
}
}
@Override
protected void onCancelled() {
ScanActivity.this.showProgress(false,"");
}
}
}

View File

@ -0,0 +1,376 @@
package kz.istt.locust;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.TextView;
import com.google.android.gms.vision.Frame;
import com.google.android.gms.vision.barcode.Barcode;
import com.google.android.gms.vision.barcode.BarcodeDetector;
import java.util.Locale;
public class SetupActivity extends Activity {
//Для смены языка на лету
//private Locale myLocale;
private SharedPreferences preferences;
private Locale locale;
private String lang;
//private OrientationEventListener mOrientationListener=null;
//public ProgressDialog dialog;
//public Handler myHandle;
public Button btnSynchronization = null; //Кнопка синхронизации
public TextView tvSynchronization = null; //
public Button btnDr = null;
public Button btnAz = null;
public Button btnEn = null;
public Button btnGr = null;
public Button btnKg = null;
public Button btnKz = null;
public Button btnRu = null;
public Button btnUz = null;
public Button btnTj = null;
public Button btnTm = null;
public Button btnAr = null;
public Button btnQR = null;
public CheckBox cbIdentifyCountryRegion = null;
public final static int TASK1_CODE = 1;
public final static int TASK2_CODE = 2;
public final static int TASK3_CODE = 3;
public final static int STATUS_START = 100;
public final static int STATUS_FINISH = 200;
//public final static String PARAM_ACTION = "ACTION";
public final static String PARAM_PINTENT = "pendingIntent";
public final static String PARAM_RESULT = "result";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_setup);
/*
mOrientationListener = new OrientationEventListener(this,
SensorManager.SENSOR_DELAY_NORMAL) {
@Override
public void onOrientationChanged(int orientation)
{
Log.e("CCALM", "Orientation changed to " + orientation);
}
};
if (mOrientationListener.canDetectOrientation() == true) {
Log.e("CCALM", "Can detect orientation");
mOrientationListener.enable();
} else {
Log.e("CCALM", "Cannot detect orientation");
mOrientationListener.disable();
}
*/
//Загрузка сохранёного языка
Tools.loadLocale(this);
tvSynchronization = (TextView)findViewById(R.id.tvSynchronization);
//Кнопочка синхронизировать
btnSynchronization = (Button) findViewById(R.id.btnSynchronization);
OnClickListener oclBtnSynchronization = new OnClickListener()
{
@Override
public void onClick(View v)
{
startService(new Intent(SetupActivity.this, MainService.class).putExtra(MainService.PARAM_ACTION, "1")); // Чтоб вызвать событие таймера в сервисе
}
};
btnSynchronization.setOnClickListener(oclBtnSynchronization);
//Выбор языка
btnDr = (Button) findViewById(R.id.btnDr);
OnClickListener oclbtnDr = new OnClickListener()
{
@Override
public void onClick(View v)
{
Tools.saveLocale(SetupActivity.this, "ps");
updateTexts();
}
};
btnDr.setOnClickListener(oclbtnDr);
//Выбор языка
btnAz = (Button) findViewById(R.id.btnAz);
OnClickListener oclBtnAz = new OnClickListener()
{
@Override
public void onClick(View v)
{
Tools.saveLocale(SetupActivity.this, "az");
updateTexts();
}
};
btnAz.setOnClickListener(oclBtnAz);
//Выбор англйского языка
btnEn = (Button) findViewById(R.id.btnEn);
OnClickListener oclBtnEn = new OnClickListener()
{
@Override
public void onClick(View v)
{
Tools.saveLocale(SetupActivity.this, "en");
updateTexts();
}
};
btnEn.setOnClickListener(oclBtnEn);
//Выбор Грузинского языка
btnGr = (Button) findViewById(R.id.btnGr);
OnClickListener oclBtnGr = new OnClickListener()
{
@Override
public void onClick(View v)
{
Tools.saveLocale(SetupActivity.this, "ka");
updateTexts();
}
};
btnGr.setOnClickListener(oclBtnGr);
//Кыргыз
btnKg = (Button) findViewById(R.id.btnKg);
OnClickListener oclBtnKg = new OnClickListener()
{
@Override
public void onClick(View v)
{
Tools.saveLocale(SetupActivity.this, "kg");
updateTexts();
}
};
btnKg.setOnClickListener(oclBtnKg);
//Выбор Казахского языка
btnKz = (Button) findViewById(R.id.btnKz);
OnClickListener oclBtnKz = new OnClickListener()
{
@Override
public void onClick(View v)
{
Tools.saveLocale(SetupActivity.this, "kk");
updateTexts();
}
};
btnKz.setOnClickListener(oclBtnKz);
//Выбор руского языка
btnRu = (Button) findViewById(R.id.btnRu);
OnClickListener oclBtnRu = new OnClickListener()
{
@Override
public void onClick(View v)
{
Tools.saveLocale(SetupActivity.this, "ru");
updateTexts();
}
};
btnRu.setOnClickListener(oclBtnRu);
//Выбор узбекского языка
btnUz = (Button) findViewById(R.id.btnUz);
OnClickListener oclBtnUz = new OnClickListener()
{
@Override
public void onClick(View v)
{
Tools.saveLocale(SetupActivity.this, "uz");
updateTexts();
}
};
btnUz.setOnClickListener(oclBtnUz);
//Выбор Таджикского языка
btnTj = (Button) findViewById(R.id.btnTj);
OnClickListener oclBtnTj = new OnClickListener()
{
@Override
public void onClick(View v)
{
Tools.saveLocale(SetupActivity.this, "tg");
updateTexts();
}
};
btnTj.setOnClickListener(oclBtnTj);
//Выбор Туркменского языка
btnTm = (Button) findViewById(R.id.btnTm);
OnClickListener oclBtnTm = new OnClickListener()
{
@Override
public void onClick(View v)
{
Tools.saveLocale(SetupActivity.this, "tk");
updateTexts();
}
};
btnTm.setOnClickListener(oclBtnTm);
//Выбор Армянского языка
btnAr = (Button) findViewById(R.id.btnAr);
OnClickListener oclBtnAr = new OnClickListener()
{
@Override
public void onClick(View v)
{
Tools.saveLocale(SetupActivity.this, "hy");
updateTexts();
}
};
btnAr.setOnClickListener(oclBtnAr);
cbIdentifyCountryRegion = (CheckBox) findViewById(R.id.cbIdentifyCountryRegion);
String prefName = "Identify";
SharedPreferences prefs = getSharedPreferences("CommonPrefs", Activity.MODE_PRIVATE);
String checked = prefs.getString(prefName, "");
if(checked.equals("") || checked.equals("1"))
cbIdentifyCountryRegion.setChecked(true);
else
cbIdentifyCountryRegion.setChecked(false);
OnClickListener oclBtnId = new OnClickListener()
{
@Override
public void onClick(View v)
{
String prefName = "Identify";
SharedPreferences prefs = getSharedPreferences("CommonPrefs", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
if(cbIdentifyCountryRegion.isChecked())
editor.putString(prefName, "1"); //Default value
else
editor.putString(prefName, "0");
editor.commit();
}
};
cbIdentifyCountryRegion.setOnClickListener(oclBtnId);
//Кнопка для сканирования QR кода
btnQR = (Button) findViewById(R.id.btnQR);
OnClickListener oclBtnQR = new OnClickListener()
{
@Override
public void onClick(View v)
{
startActivity(new Intent(SetupActivity.this, ScanActivity.class));
}
};
btnQR.setOnClickListener(oclBtnQR);
//1 диалог на всё
/*dialog = new ProgressDialog(SetupActivity.this);
dialog.setMessage("Синхронизация...");
dialog.setIndeterminate(true);
dialog.setCancelable(true);*/
}
/** СМ. http://developer.android.com/reference/android/app/Activity.html
* Происходит при старте и при возврате на этот Activity
* */
@Override
public void onStart()
{
super.onStart();
//Для возможности синхронизации прогресс бара передаём ниточку в поток
PendingIntent pi = createPendingResult(TASK1_CODE, new Intent(this, MainService.class), 0);
Intent intent = new Intent(this, MainService.class);
intent.putExtra(MainService.PARAM_ACTION, "2");
intent.putExtra(PARAM_PINTENT, pi);
startService(intent);
}
@Override
protected void onStop() {
super.onStop();
/*
//Удаляем слушателя
Intent intent = new Intent(this, MainService.class);
intent.putExtra(MainService.PARAM_ACTION, "3");
startService(intent);
*/
}
@Override
protected void onDestroy() {
super.onDestroy();
//mOrientationListener.disable();
}
@Override
public void onConfigurationChanged(Configuration newConfig)
{
super.onConfigurationChanged(newConfig);
/*locale = new Locale(lang);
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config, null);*/
//updateTexts();
}
/*@Override
public void onOrientationChanged(int arg0)
{
}*/
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.setup, menu);
return true;
}
//Обновление UI элементов текущего окна (обновлять необходимо только окно, в котором происходит смена локали):
private void updateTexts()
{
Intent intent = getIntent();
finish();
startActivity(intent);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
//Пришли данные о статусе синхронизации
if (resultCode == STATUS_FINISH)
{
int cnt = data.getIntExtra(PARAM_RESULT, 0);
tvSynchronization.setText("Synchronization tasks: "+ String.valueOf(cnt));
}
}
}

View File

@ -0,0 +1,73 @@
package kz.istt.locust;
import android.app.Activity;
import android.content.Intent;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.MotionEvent;
public class SplashScreen extends Activity {
//how long until we go to the next activity
protected int _splashTime = 1500;
private Thread splashTread;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
//Создаём базу
DbOpenHelper dboh=new DbOpenHelper(this);
SQLiteDatabase db = dboh.getReadableDatabase();
db.close();
dboh.close();
final SplashScreen sPlashScreen = this;
//Загрузка сохраненного языка
Tools.loadLocale(this);
// thread for displaying the SplashScreen
splashTread = new Thread() {
@Override
public void run() {
try {
synchronized(this){
//wait 5 sec
wait(_splashTime);
}
} catch(InterruptedException e) {}
finally {
finish();
//start a new activity
Intent i = new Intent();
i.setClass(sPlashScreen, MainActivity.class);
startActivity(i);
finish();
}
}
};
splashTread.start();
}
//Function that will handle the touch
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
synchronized(splashTread){
splashTread.notifyAll();
}
}
return true;
}
}

View File

@ -0,0 +1,439 @@
package kz.istt.locust;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.Spinner;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
/*
import java.util.Locale;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.util.DisplayMetrics;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.Spinner;
import android.widget.Toast;
import android.widget.AdapterView.OnItemSelectedListener;
*/
public class Tools
{
public static boolean setListViewHeightBasedOnItems(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter != null) {
int numberOfItems = listAdapter.getCount();
// Get total height of all items.
int totalItemsHeight = 0;
for (int itemPos = 0; itemPos < numberOfItems; itemPos++) {
View item = listAdapter.getView(itemPos, null, listView);
float px = 500 * (listView.getResources().getDisplayMetrics().density);
item.measure(View.MeasureSpec.makeMeasureSpec((int)px, View.MeasureSpec.AT_MOST), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
totalItemsHeight += item.getMeasuredHeight();
}
// Get total height of all item dividers.
int totalDividersHeight = listView.getDividerHeight() *
(numberOfItems - 1);
// Get padding
int totalPadding = listView.getPaddingTop() + listView.getPaddingBottom();
// Set list height.
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalItemsHeight + totalDividersHeight + totalPadding;
listView.setLayoutParams(params);
listView.requestLayout();
return true;
} else {
return false;
}
}
//Получить текущую временную зону в виде 00:00:00
public static String getTimezone()
{
Calendar cal = Calendar.getInstance();
TimeZone tz = cal.getTimeZone();
int offset=tz.getRawOffset()/1000;
int hours = offset / 3600;
int minutes = (offset % 3600) / 60;
int seconds = offset % 60;
return Tools.numConvert(String.format("%02d:%02d:%02d", hours, minutes, seconds));
}
//Преобразовать арабские и индийские в современные цифры
public static String numConvert(String str)
{
if(str==null) return null;
String persian = "۰۱۲۳۴۵۶۷۸۹";
String arabic = "٩٨٧٦٥٤٣٢١٠";
String num = "0123456789";
//Заменяю персидские
for(int i=0;i<str.length();i++)
{
for(int j=0;j<persian.length();j++)
{
if(str.charAt(i)==persian.charAt(j))
{
str = str.substring(0,i) + num.charAt(j) + str.substring(i+1);
break;
}
}
}
//Заменяю арабские
for(int i=0;i<str.length();i++)
{
for(int j=0;j<arabic.length();j++)
{
if(str.charAt(i)==arabic.charAt(j))
{
str = str.substring(0,i) + num.charAt(j) + str.substring(i+1);
break;
}
}
}
return str;
}
public static String convertStreamToString(InputStream is, int size) throws Exception {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line).append("\n");
if(size!=-1 && sb.length()>size)
break;
}
reader.close();
return sb.toString();
}
public static String getStringFromFile (String filePath, int size) throws Exception {
File fl = new File(filePath);
FileInputStream fin = new FileInputStream(fl);
String ret = convertStreamToString(fin,size);
//Make sure you close all streams.
fin.close();
return ret;
}
public static final String md5(final String str)
{
try {
// Create MD5 Hash
MessageDigest digest = java.security.MessageDigest
.getInstance("MD5");
digest.update(str.getBytes());
byte messageDigest[] = digest.digest();
// Create Hex String
StringBuffer hexString = new StringBuffer();
for (int i = 0; i < messageDigest.length; i++) {
String h = Integer.toHexString(0xFF & messageDigest[i]);
while (h.length() < 2)
h = "0" + h;
hexString.append(h);
}
return hexString.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return "";
}
/**
* Получить Integer из текста
*/
public static Boolean getBoolean(String val)
{
if(val==null || val.equals("") || val.equals("null")) return null;
if(val.equals("1") || val.equals("t")) return Boolean.valueOf(true);
if(val.equals("0") || val.equals("f")) return Boolean.valueOf(false);
return null;
}
/**
* Получить Integer из текста
*/
public static Integer getInt(String val)
{
if(val==null || val.equals("") || val.equals("null")) return null;
return Integer.parseInt(val);
}
/**
* Получить Long из текста
*/
public static Long getLong(String val, Long def)
{
if(val==null || val.equals("") || val.equals("null")) return def;
return Long.parseLong(val);
}
/**
* Получить Double из текста
*/
public static Double getDouble(String val, Double def)
{
if(val==null || val.equals("") || val.equals("null")) return def;
return Double.parseDouble(val);
}
/**
* вывод в лог данных из курсора
* @param c - открытый курсор
*/
public static void logCursor(Cursor c)
{
Log.d("LOG_TAG", "Cursor:");
if (c != null)
{
if (c.moveToFirst())
{
String str;
do {
str = "";
for (String cn : c.getColumnNames())
{
str = str.concat(cn + " = " + c.getString(c.getColumnIndex(cn)) + "; ");
}
Log.d("LOG_TAG", str);
} while (c.moveToNext());
}
} else
Log.d("LOG_TAG", "Cursor is null");
}
/**
* Выбрать в списке по названию если нет то создать элемент в конце списка
* @param item название
*/
public static void selSpinnerIC(Spinner spi, String item)
{
if(item == null) item = "";
int pos=-1;
for(int i=0;i<spi.getCount();i++)
{
if(spi.getItemAtPosition(i).toString().equals(item))
{ pos = i;
break;
}
}
if(pos==-1)
{
ArrayAdapter<String> dataAdapter = (ArrayAdapter<String>)spi.getAdapter();
//SpinnerAdapter dataAdapter = spi.getAdapter();
if(dataAdapter!=null)
{ dataAdapter.add(item);
pos=spi.getCount()-1;
}//else pos=INVALID_POSITION;
}
spi.setSelection(pos);
}
//Загрузка ранее сохраненной локали
public static void loadLocale(Context context)
{
String langPref = "Language";
SharedPreferences prefs = context.getSharedPreferences("CommonPrefs", Activity.MODE_PRIVATE);
String language = prefs.getString(langPref, "");
Tools.changeLang0(context, language);
}
//Сохранение текущей локали
public static void saveLocale(Context context, String lang)
{
String langPref = "Language";
SharedPreferences prefs = context.getSharedPreferences("CommonPrefs", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
editor.putString(langPref, lang);
editor.commit();
Tools.changeLang0(context,lang);
}
//Смена языка в приложении
private static void changeLang0(Context context, String lang)
{
if (lang.equalsIgnoreCase(""))
return;
Locale myLocale = new Locale(lang);
Locale.setDefault(myLocale);
android.content.res.Configuration config = new android.content.res.Configuration();
config.locale = myLocale;
context.getResources().updateConfiguration(config, context.getResources().getDisplayMetrics());
}
/*Получить короткое имя языка*/
public static String getLang()
{
/* android.content.res.Configuration config = new android.content.res.Configuration();
return config.locale.getDisplayLanguage();
*/
return Locale.getDefault().getLanguage();
}
/** Дату время в виде строки "HH:mm:ss dd.MM.yyyy" в секунд с 1970 года
* */
public static Long getUnixDateTime(String dateString)
{
SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss dd.MM.yyyy");
Date convertedDate = new Date();
try {
convertedDate = dateFormat.parse(dateString);
} catch (java.text.ParseException e) {
e.printStackTrace();
return null;
}
return Long.valueOf(convertedDate.getTime()/1000L); //Секунд с 1970 года
}
/** Время в виде строки "HH:mm:ss" в секунды
* */
public static Integer getUnixTime(String timeString)
{
SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
Date convertedDate = new Date();
try {
convertedDate = dateFormat.parse(timeString);
} catch (java.text.ParseException e)
{
e.printStackTrace();
return null;
}
return Integer.valueOf((int)(convertedDate.getTime()/1000L)); //Секунд
}
/** Boolean из Spinner 0 - null 1 - true 2 - false
*/
public static Boolean getBooleanFromSpi(Spinner spi)
{
if(spi==null) return null;
switch(spi.getSelectedItemPosition())
{
case 1:
return Boolean.valueOf(true);
case 2:
return Boolean.valueOf(false);
}
return null;
}
//Направление ветра по номеру спинера (8 сторон света)
public static Integer getDirection(Spinner spi)
{
//Направление ветра по номеру
Integer dir=null;
if(spi.getSelectedItemPosition()==0) dir=null;
else if(spi.getSelectedItemPosition()==1) dir=0;
else if(spi.getSelectedItemPosition()==2) dir=180;
else if(spi.getSelectedItemPosition()==3) dir=270;
else if(spi.getSelectedItemPosition()==4) dir=90;
else if(spi.getSelectedItemPosition()==5) dir=45;
else if(spi.getSelectedItemPosition()==6) dir=315;
else if(spi.getSelectedItemPosition()==7) dir=135;
else if(spi.getSelectedItemPosition()==8) dir=225;
else
{ dir= Integer.getInteger(spi.getSelectedItem().toString());
}
return dir;
}
//Выставить направление ветра в спинере
public static void setDirection(Spinner spi, String dir)
{
if(spi == null) return;
if(dir == null || dir.equals("")) spi.setSelection(0);
else if(dir.equals("0")) spi.setSelection(1);
else if(dir.equals("180")) spi.setSelection(2);
else if(dir.equals("270")) spi.setSelection(3);
else if(dir.equals("90")) spi.setSelection(4);
else if(dir.equals("45")) spi.setSelection(5);
else if(dir.equals("315")) spi.setSelection(6);
else if(dir.equals("135")) spi.setSelection(7);
else if(dir.equals("225")) spi.setSelection(8);
else Tools.selSpinnerIC(spi,dir);
}
//Получить строку заменив NULL пустой строкой
public static String getStringFromCursor(Cursor cursor, String name)
{
if(cursor==null || name==null) return "";
String str=cursor.getString(cursor.getColumnIndex(name));
if(str==null || str=="null") str="";
return str;
}
//Изменяем размер пропорционально
public static Bitmap getResizeBMP(Bitmap bm, int newSize) {
float newWidth;
float newHeight;
if(bm.getWidth()>bm.getHeight())
{
newWidth = newSize;
newHeight = bm.getHeight() * ((float)newSize / bm.getWidth());
}else
{
newHeight = newSize;
newWidth = bm.getWidth() * ((float)newSize / bm.getHeight());
}
return getResizedBitmap(bm,(int)newWidth,(int)newHeight);
}
public static Bitmap getResizedBitmap(Bitmap bm, int newWidth, int newHeight)
{
int width = bm.getWidth();
int height = bm.getHeight();
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
// CREATE A MATRIX FOR THE MANIPULATION
Matrix matrix = new Matrix();
// RESIZE THE BIT MAP
matrix.postScale(scaleWidth, scaleHeight);
matrix.postRotate(90);
// "RECREATE" THE NEW BITMAP
Bitmap resizedBitmap = Bitmap.createBitmap(
bm, 0, 0, width, height, matrix, false);
bm.recycle();
return resizedBitmap;
}
}

View File

@ -0,0 +1,67 @@
package kz.istt.locust;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class XMLTools
{
/**
* Вернуть значение первой попавшийся CDATA
* @return строка
*/
public static String getCDATAValue(Node node)
{
if(node==null) return "";
NodeList items = node.getChildNodes();
for (int i=0;i<items.getLength();i++)
{
Node n=items.item(i);
if(n.getNodeName().equals("#cdata-section"))
return n.getNodeValue();
}
return "";
}
/** Найти узел по атрибуту
*/
public static Node findNodeOnAttribute(Node node, String nodename, String attribute, String val)
{
if(node==null) return null;
NodeList items = node.getChildNodes();
for (int i=0;i<items.getLength();i++)
{
Node n=items.item(i);
if(n.getNodeName().equals(nodename))
{
NamedNodeMap nnm=n.getAttributes();
if(nnm.getNamedItem(attribute).getNodeValue().equals(val)) return n;
}
}
return null;
}
/**
* Найти узел по имени
* @param node
* @param nodename
* @return
*/
public static Node findFirstNode(Node node, String nodename)
{
if(node==null || nodename==null) return null;
NodeList items = node.getChildNodes();
for (int i=0;i<items.getLength();i++)
{
Node n=items.item(i);
if(n.getNodeName().equals(nodename))
{
return n;
}
}
return null;
}
}

View File

@ -0,0 +1,14 @@
/**
* Created by IntelliJ IDEA.
* User: igor
* Date: 09.03.2007
* Time: 0:53:45
* To change this template use File | Settings | File Templates.
*/
package tctable;
public class Point
{
public double x=0;
public double y=0;
}

View File

@ -0,0 +1,388 @@
package tctable;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
public class TCField
{
//Типы данных
static int BD_UINT1 = 0; //1 байт без знаковый
static int BD_UINT2 = 1; //2 байта без знаковый
static int BD_UINT4 = 3; //4 байта без знаковый
static int BD_INT1 = 10; //1 байт со знаковый
static int BD_INT2 = 11; //2 байта со знаковый
static int BD_INT4 = 13; //4 байта со знаковый
static int BD_INT8 = 17; //8 байт со знаковый
static int BD_FLOAT4 = 20; //4 байта
static int BD_FLOAT8 = 22; //8 байт double
static int BD_UTF8_1 = 100; //100 - utf8_1 string 1й байт размер строки в байтах
static int BD_UTF8_2 = 101; //101 - utf8_2 string 1х 2 байта размер строки в байтах
static int BD_UTF8_4 = 102; //102 - utf8_4 string 1х 4 байта размер строки в байтах
static int BD_BLOB_2 = 141;
static int BD_BLOB_4 = 143; //Двоичные данные uint4 количество байт
public String name=""; //Название столбца
public int type=-1; //Тип данных
public byte[] value=null; //Запакованые данные
public TCField(String name, int type)
{
this.name=name;
this.type=type;
}
public TCField(String name, String type)
{
this.name=name;
//this.type=type;
this.type= TCField.BD_UTF8_2; //Defalt type
//From PostgreSQL and MySQL
if(type.equals("bool") || type.equals("tinyint")) { this.type= TCField.BD_UINT1; } else
if(type.equals("int4") || type.equals("int") || type.equals("serial") || type.equals("bigint")) { this.type= TCField.BD_INT4; } else //bigint немного неправильно потому что это 64 бита но для андрод приложения не сделал
if(type.equals("int8")) { this.type= TCField.BD_INT8; } else
if(type.equals("float4") || type.equals("float")) { this.type= TCField.BD_FLOAT4; } else
if(type.equals("float8") || type.equals("NUMBER")) { this.type= TCField.BD_FLOAT8; } else
if(type.equals("varchar") || type.equals("VARCHAR2")) { this.type= TCField.BD_UTF8_2; } else
if(type.equals("text")) { this.type= TCField.BD_UTF8_4; } else
if(type.equals("bytea") || type.equals("longblob")) { this.type= TCField.BD_BLOB_4; } else
if(type.equals("timestamptz")) { this.type= TCField.BD_UTF8_1; } else
if(type.equals("timestamp")) { this.type= TCField.BD_UTF8_1; } else
if(type.equals("date")) { this.type= TCField.BD_UTF8_1; }
}
private int byteArrayToInt(byte[] b, int start, int length)
{
int dt = 0;
if ((b[start] & 0x80) != 0)
dt = Integer.MAX_VALUE;
for (int i = 0; i < length; i++)
dt = (dt << 8) + (b[start++] & 255);
return dt;
}
/*
private byte[] intToByteArray(int n, int byteCount)
{
byte[] res = new byte[byteCount];
for (int i = 0; i < byteCount; i++)
res[byteCount - i - 1] = (byte) ((n >> i * 8) & 255);
return res;
}
*/
//Прочитать значение из потока в соответствии с типом
public void ReadValue(InputStream fileHandle) throws IOException
{
if(this.type== TCField.BD_UINT1)
{
value=new byte[1];
fileHandle.read(value);
}else
if(this.type== TCField.BD_UINT2)
{
value=new byte[2];
fileHandle.read(value);
}else
if(this.type== TCField.BD_UINT4)
{
value=new byte[4];
fileHandle.read(value);
}else
if(this.type== TCField.BD_INT1)
{
value=new byte[1];
fileHandle.read(value);
}else
if(this.type== TCField.BD_INT2)
{
value=new byte[2];
fileHandle.read(value);
}else
if(this.type== TCField.BD_INT4)
{
value=new byte[4];
fileHandle.read(value);
}else
if(this.type== TCField.BD_INT8)
{
value=new byte[8];
fileHandle.read(value);
}else
if(this.type== TCField.BD_FLOAT4)
{
value=new byte[4];
fileHandle.read(value);
}else
if(this.type== TCField.BD_FLOAT8)
{
value=new byte[8];
fileHandle.read(value);
}else
if(this.type== TCField.BD_UTF8_1)
{
byte[] s=new byte[1];
fileHandle.read(s);
if(s[0]==0) value=null;
else
{
value=new byte[s[0]];
fileHandle.read(value);
}
}else
if(this.type== TCField.BD_UTF8_2)
{
int s= Tools.readUShort(fileHandle);
if(s==0) value=null;
else
{
value=new byte[s];
fileHandle.read(value);
}
}else
if(this.type== TCField.BD_BLOB_4)
{
byte[] ss=new byte[4];
fileHandle.read(ss);
int s=byteArrayToInt(ss, 0, 4);
if(s==0) value=null;
else
{
value=new byte[s];
fileHandle.read(value);
}
}
}
public String getStrVal()
{
String result=null;
try
{
if(value==null) result = "";
if(type== TCField.BD_UINT1) result = String.valueOf(getUByteVal());
if(type== TCField.BD_UINT4) result = String.valueOf(getUIntVal());
if(type== TCField.BD_INT4) result = String.valueOf(getIntVal());
if(type== TCField.BD_FLOAT4) result = String.valueOf(getFloatVal());
if(type== TCField.BD_UTF8_1 || type== TCField.BD_UTF8_2)
{
result = new String(value, "UTF8");
}
} catch (Exception e) {}
return result;
}
public int getIntVal()
{
int i1 = value[0] & 0xff;
int i2 = value[1] & 0xff;
int i3 = value[2] & 0xff;
int i4 = value[3] & 0xff;
int val = i4 << 24 | i3 << 16 | i2 << 8 | i1;
return val;
}
/** Пока не использую но если буду использовать протестировать с большими числами */
public long getUIntVal()
{
long ch1, ch2, ch3, ch4, count;
ch1 = value[0] & 0xff;
ch2 = value[1] & 0xff;
ch3 = value[2] & 0xff;
ch4 = value[3] & 0xff;
count = (ch4 << 24) | (ch3 << 16) | (ch2 << 8) | ch1;
return count;
}
public short getUByteVal()
{
return (short) (value[0] & 0xff);
}
public float getFloatVal()
{
float f;
int ch1, ch2, ch3, ch4, count;
ch1 = value[0] & 0xFF;
ch2 = value[1] & 0xFF;
ch3 = value[2] & 0xFF;
ch4 = value[3] & 0xFF;
count = (ch4 << 24) | (ch3 << 16) | (ch2 << 8) | ch1;
f = Float.intBitsToFloat(count);
return f;
}
public boolean setValue(String val)
{
boolean result=true;
if(val==null)
{ value=null;
}else if(type== TCField.BD_UINT1)
{
if(val.equals("f") || val.equals("false")) val="0";
else if(val.equals("t") || val.equals("true")) val="1";
int v= Integer.parseInt(val);
if(v<0 || v>255) result=false;
value=new byte[1];
value[0]=(byte)v;
}else if(type== TCField.BD_UINT2)
{
int v= Integer.parseInt(val);
if(v<0 || v>65535) result=false;
value=new byte[2];
value[0] = (byte)((v & 0x000000ff));
value[1] = (byte)((v & 0x0000ff00) >> 8);
}else if(type== TCField.BD_UINT4)
{
long v= Long.parseLong(val);
value=new byte[4];
value[0] = (byte)((v & 0x000000ff));
value[1] = (byte)((v & 0x0000ff00) >> 8);
value[2] = (byte)((v & 0x00ff0000) >> 16);
value[3] = (byte)((v & 0xff000000) >> 24);
}else if(type== TCField.BD_INT1)
{
int v= Integer.parseInt(val);
value=new byte[1];
value[0]=(byte)v;
}else if(type== TCField.BD_INT2)
{
int v= Integer.parseInt(val);
value=new byte[2];
value[0] = (byte)((v & 0x000000ff));
value[1] = (byte)((v & 0x0000ff00) >> 8);
}else if(type== TCField.BD_INT4)
{
long v= Long.parseLong(val);
value=new byte[4];
value[0] = (byte)((v & 0x000000ff));
value[1] = (byte)((v & 0x0000ff00) >> 8);
value[2] = (byte)((v & 0x00ff0000) >> 16);
value[3] = (byte)((v & 0xff000000) >> 24);
}else if(type== TCField.BD_INT8)
{
long v= Long.parseLong(val);
value=new byte[8];
value[0] = (byte) (v & 0x00000000000000ffl);
value[1] = (byte)((v & 0x000000000000ff00l) >> 8);
value[2] = (byte)((v & 0x0000000000ff0000l) >> 16);
value[3] = (byte)((v & 0x00000000ff000000l) >> 24);
value[4] = (byte)((v & 0x000000ff00000000l) >> 32);
value[5] = (byte)((v & 0x0000ff0000000000l) >> 40);
value[6] = (byte)((v & 0x00ff000000000000l) >> 48);
value[7] = (byte)((v & 0xff00000000000000l) >> 56);
}else if(type== TCField.BD_FLOAT4)
{
Float v= Float.parseFloat(val);
int iv= Float.floatToIntBits(v);
value=new byte[4];
value[0] = (byte)((iv & 0x000000ff));
value[1] = (byte)((iv & 0x0000ff00) >> 8);
value[2] = (byte)((iv & 0x00ff0000) >> 16);
value[3] = (byte)((iv & 0xff000000) >> 24);
}else if(type== TCField.BD_FLOAT8)
{
Double v= Double.parseDouble(val);
long iv= Double.doubleToLongBits(v);
value=new byte[8];
value[0] = (byte)((iv & 0x00000000000000ffl));
value[1] = (byte)((iv & 0x000000000000ff00l) >> 8);
value[2] = (byte)((iv & 0x0000000000ff0000l) >> 16);
value[3] = (byte)((iv & 0x00000000ff000000l) >> 24);
value[4] = (byte)((iv & 0x000000ff00000000l) >> 32);
value[5] = (byte)((iv & 0x0000ff0000000000l) >> 40);
value[6] = (byte)((iv & 0x00ff000000000000l) >> 48);
value[7] = (byte)((iv & 0xff00000000000000l) >> 56);
}else if(type== TCField.BD_UTF8_1)
{
value=null;
if(val!=null && !val.equals(""))
{
byte[] b=null;
try {
b = val.getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
result=false;
}
if(b!=null)
{
int len=b.length;
if(len>255) len=255;
value=new byte[len+1];
value[0]=(byte)len;
for(int i=0;i<len;i++)
{
value[i+1]=b[i];
}
}
}
}else if(type== TCField.BD_UTF8_2)
{
value=null;
if(val!=null && !val.equals(""))
{
byte[] b=null;
try {
b = val.getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
result=false;
}
if(b!=null)
{
int len=b.length;
if(len>65535) len=65535;
value=new byte[len+2];
value[0]=(byte) (len & 0x000000ff);
value[1]=(byte)((len & 0x0000ff00) >> 8);
for(int i=0;i<len;i++)
{
value[i+2]=b[i];
}
}
}
}else if(type== TCField.BD_UTF8_4)
{
value=null;
if(val!=null && !val.equals(""))
{
byte[] b=null;
try {
b = val.getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
result=false;
}
if(b!=null)
{
int len=b.length;
value=new byte[len+4];
value[0]=(byte) (len & 0x000000ff);
value[1]=(byte)((len & 0x0000ff00) >> 8);
value[2]=(byte)((len & 0x00ff0000) >> 16);
value[3]=(byte)((len & 0xff000000) >> 24);
for(int i=0;i<len;i++)
{
value[i+4]=b[i];
}
}
}
}
/*
if($this->type==TCField::$BD_BLOB_4)
{ return pack("I",strlen($value)).$value;
}
*/
return result;
}
}

View File

@ -0,0 +1,200 @@
package tctable;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
public class TCTable
{
public int id=0; //Идентификатор таблицы
public String name=""; //Название таблицы
public List<TCField> fields=new ArrayList<TCField>(); //Список полей
private int nc=0; //Байтов под NULL значения
private byte[] m_NULL=null; //NULL значения
private InputStream m_file;
/**
* Конструктор
* @param Строка name Название таблицы
* @param Целое id Идентификатор таблицы (обычно уникальный)
*/
public TCTable(String name, int id)
{ this.name=name;
this.id=id;
}
//Открыть таблицу по названию файла
/*function OpenTableF(file)
{
if(file_exists(file))
{
this.OpenTableH(fopen(file,'r'));
}
}*/
//Открыть таблицу из потока HANDLE
public boolean OpenTableH(InputStream handle) throws IOException
{
this.m_file=handle;
DataInputStream dis = new DataInputStream(handle);
if(Tools.readUShort(dis)!=65500) return false; //id файла
if(Tools.readUShort(dis)!=1) return false; //Версия файла
this.id= Tools.readInt(dis); //ID таблицы или запроса (4 байта можно сделать 2)
if(dis.readByte()!=0) return false; //Только плотные таблицы
//Считываем название таблицы
this.name = Tools.readUTF8_1(dis);
//Считываем столбцы
int count=dis.readUnsignedByte(); //Количество столбцов
for(int i=0;i<count;i++)
{
TCField field=new TCField(Tools.readUTF8_1(dis), dis.readUnsignedByte());
this.addField(field);
}
return true;
}
//Открыть таблицу из потока
//OpenTable
//Прочитать следующую запись из потока
public boolean ReadNextRecord()
{
Boolean result=true;
try
{
DataInputStream dis = new DataInputStream(m_file);
//if(m_file.available()) return false; //Неработает
if(dis.available()==0)
return false;
//Считываем NULL значения
if(m_NULL==null) m_NULL = new byte[nc];
for(int i=0;i<nc;i++)
{
m_NULL[i]=(byte)dis.readUnsignedByte();
}
clearRows();
for(int i=0;i<fields.size();i++)
{
if(Tools.getBit(m_NULL,i))
{
fields.get(i).ReadValue(m_file);
}
}
}catch(Exception e)
{
result=false;
}
return result;
}
//Добавить поле к таблице
public void addField(TCField field)
{ if(field!=null)
{ fields.add(field);
this.nc=(int) Math.ceil(fields.size()/8.0); //Байтов под NULL
m_NULL=new byte[nc];
}
}
//Получить заголовок плотной таблицы в виде двоичной строки
public boolean getHeader(OutputStream os)
{
boolean result=true;
try {
//File ID: 2 bytes.
os.write((65500 & 0x000000ff));
os.write((65500 & 0x0000ff00) >> 8);
//File version: 2 bytes.
os.write((1 & 0x000000ff));
os.write((1 & 0x0000ff00) >> 8);
//Table ID (or Request ID): 4 bytes.
os.write((this.id & 0x000000ff));
os.write((this.id & 0x0000ff00) >> 8);
os.write((this.id & 0x00ff0000) >> 16);
os.write((this.id & 0xff000000) >> 24);
//Table type: 1 byte (0- "Dense" 1- "Loose")
os.write(0);
//UTF8_1 String
byte[] ba = this.name.getBytes("UTF-8");
os.write(ba.length);
os.write(ba);
//Count of fields: 1 byte.
os.write(this.fields.size());
//Write name and type id
for(int i=0;i<this.fields.size();i++)
{
ba = this.fields.get(i).name.getBytes("UTF-8");
os.write(ba.length);
os.write(ba);
os.write(this.fields.get(i).type);
}
} catch (IOException e) {
result=false;
}
return result;
}
//Получить данные 1 записи в виде строки
public boolean getCol(OutputStream os)
{
boolean result=true;
//Запишем NULL значения побайтно (1-есть данные 0-нету данных)
int nc=(int) Math.ceil(fields.size()/8.0); //Байтов под NULL
byte[] fNULL=new byte[nc];
for(int i=0;i<nc*8;i++)
{
if(i<this.fields.size() && this.fields.get(i).value!=null)
{
Tools.setBit(fNULL,i);
}
}
//Write NULL fields
try {
os.write(fNULL);
} catch (IOException e1) {
result=false;
}
//Запишем сами данные в строку
for(int i=0;i<fields.size();i++)
{
try {
if(fields.get(i).value!=null)
os.write(fields.get(i).value);
} catch (IOException e) {
result=false;
}
}
return result;
}
//Row очистить запись
void clearRows()
{ for(int i=0;i<fields.size();i++)
{
fields.get(i).value=null;
}
}
//Получить обьект столбца по имени
public TCField getRowByName(String name)
{ for(int i=0;i<fields.size();i++)
{ if(fields.get(i).name.toUpperCase().equals(name.toUpperCase())) return fields.get(i);
}
return null;
}
//Получить объект столбца по номеру
TCField getRowByNum(int num)
{ return fields.get(num);
}
}

View File

@ -0,0 +1,273 @@
package tctable;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.Calendar;
import java.util.TimeZone;
public class Tools {
public static String readStringFromInputStream(InputStream inputStream) {
ByteArrayOutputStream result = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int length;
try {
while ((length = inputStream.read(buffer)) != -1) {
result.write(buffer, 0, length);
}
} catch (IOException e1) {
e1.printStackTrace();
}
// StandardCharsets.UTF_8.name() > JDK 7
try {
return result.toString("UTF-8");
} catch (UnsupportedEncodingException e) {
}
return "";
}
//Преобразовать арабские и индийские в современные цифры
public static String numConvert(String str)
{
if(str==null) return null;
String persian = "۰۱۲۳۴۵۶۷۸۹";
String arabic = "٩٨٧٦٥٤٣٢١٠";
String num = "0123456789";
//Заменяю персидские
for(int i=0;i<str.length();i++)
{
for(int j=0;j<persian.length();j++)
{
if(str.charAt(i)==persian.charAt(j))
{
str = str.substring(0,i) + num.charAt(j) + str.substring(i+1);
break;
}
}
}
//Заменяю арабские
for(int i=0;i<str.length();i++)
{
for(int j=0;j<arabic.length();j++)
{
if(str.charAt(i)==arabic.charAt(j))
{
str = str.substring(0,i) + num.charAt(j) + str.substring(i+1);
break;
}
}
}
return str;
}
//Получить бит по его номеру нумерация лева на право
public static boolean getBit(byte[] mas, int pos)
{
int n=(int) Math.floor(pos/8.0);
int b=mas[n];
pos=pos - n * 8;
if(((b << pos) & 128) == 128)
return true;
else
return false;
}
//Установить 1й бит в номер нумерация с лева на право
public static void setBit(byte[] mas, int pos)
{
int n=(int) Math.floor(pos/8.0);
pos=pos - n * 8;
mas[n] = (byte)(mas[n] | (128 >> pos));
}
public static String readUTF8_1(InputStream handle) throws IOException
{
byte[] tmp=new byte[handle.read()];
handle.read(tmp);
return new String(tmp, "UTF8");
}
public static float readFloat(DataInputStream InStream) throws IOException
{
float f;
int ch1, ch2, ch3, ch4, count;
ch1 = InStream.readUnsignedByte();
ch2 = InStream.readUnsignedByte();
ch3 = InStream.readUnsignedByte();
ch4 = InStream.readUnsignedByte();
count = (ch4 << 24) | (ch3 << 16) | (ch2 << 8) | ch1;
f = Float.intBitsToFloat(count);
return f;
}
public static int readInt(DataInputStream InStream) throws IOException
{
int ch1, ch2, ch3, ch4, count;
ch1 = InStream.readUnsignedByte();
ch2 = InStream.readUnsignedByte();
ch3 = InStream.readUnsignedByte();
ch4 = InStream.readUnsignedByte();
count = (ch4 << 24) | (ch3 << 16) | (ch2 << 8) | ch1;
return count;
}
public static short readShort(DataInputStream InStream) throws IOException
{
int ch1, ch2, count;
ch1 = InStream.readUnsignedByte();
ch2 = InStream.readUnsignedByte();
count = (ch2 << 8) | ch1;
return (short)count;
}
public static int readUShort(InputStream InStream) throws IOException
{
int ch1, ch2;
ch1 = InStream.read();
ch2 = InStream.read();
return (ch2 << 8) | ch1;
}
public static String afterLast(String str, String ch)
{
int i=str.lastIndexOf(ch);
if(i!=-1)
{
return str.substring(i+ch.length());
}
return "";
}
public static String beforeLast(String str, String ch)
{
int i=str.lastIndexOf(ch);
if(i!=-1)
{
return str.substring(0,i);
}
return "";
}
public static String beforeFirst(String str, String ch)
{
int i=str.indexOf(ch);
if(i!=-1)
{
return str.substring(0,i);
}
return "";
}
//узнать точку пересичений 2х линай если x=0 и y=0 то не пересиклась
public static Point getCrossingLine(Point PHead0, Point PTail0, Point PHead1, Point PTail1)
{
Point rezPoint = new Point();
double a0, b0, c0, a1, b1, c1;
boolean bRez = true;
a0 = PTail0.y - PHead0.y;
b0 = PHead0.x - PTail0.x;
c0 = PTail0.x * PHead0.y - PHead0.x * PTail0.y;
a1 = PTail1.y - PHead1.y;
b1 = PHead1.x - PTail1.x;
c1 = PTail1.x * PHead1.y - PHead1.x * PTail1.y;
if (b1 == 0) rezPoint.x = PHead1.x;//если перпендикулярна oy
else rezPoint.x = (-(b0 * c1 / b1) + c0) / ((b0 * a1 / b1) - a0);
if (a1 == 0) rezPoint.y = PHead1.y;//если перпендикулярна oy
else rezPoint.y = (-(c1 * a0 / a1) + c0) / ((a0 * b1 / a1) - b0);
//проверка на вхождение в отрезоки (с погрешностью 0.0000001 (зачем понадобилась погрешность?))
//по x
if ((rezPoint.x < Math.min(PHead0.x, PTail0.x) - 0.0000001) || (rezPoint.x > Math.max(PHead0.x, PTail0.x) + 0.0000001))
bRez = false;
if ((rezPoint.x < Math.min(PHead1.x, PTail1.x) - 0.0000001) || (rezPoint.x > Math.max(PHead1.x, PTail1.x) + 0.0000001))
bRez = false;
//по y
if ((rezPoint.y < Math.min(PHead0.y, PTail0.y) - 0.0000001) || (rezPoint.y > Math.max(PHead0.y, PTail0.y) + 0.0000001))
bRez = false;
if ((rezPoint.y < Math.min(PHead1.y, PTail1.y) - 0.0000001) || (rezPoint.y > Math.max(PHead1.y, PTail1.y) + 0.0000001))
bRez = false;
if (!bRez)
{
rezPoint.x = 0;
rezPoint.y = 0;
}
return rezPoint;
}
public static Point getCrossingLine2(Point PHead0,Point PTail0,Point PHead1,Point PTail1)
{
boolean bRez=true;
Point rezPoint = new Point();
rezPoint.x=0;
rezPoint.y=0;
double a0,b0,c0,a1,b1,c1;
a0=PTail0.y-PHead0.y;
b0=PHead0.x-PTail0.x;
c0=PTail0.x*PHead0.y-PHead0.x*PTail0.y;
a1=PTail1.y-PHead1.y;
b1=PHead1.x-PTail1.x;
c1=PTail1.x*PHead1.y-PHead1.x*PTail1.y;
if (b1==0) rezPoint.x=PHead1.x;//если перпендикулярна oy
else rezPoint.x=(-(b0*c1/b1)+c0)/((b0*a1/b1)-a0);
if (a1==0) rezPoint.y=PHead1.y;//если перпендикулярна ox
else rezPoint.y=(-(c1*a0/a1)+c0)/((a0*b1/a1)-b0);
//по x
if (rezPoint.x<Math.min(PHead0.x,PTail0.x)||rezPoint.x>Math.max(PHead0.x,PTail0.x))
bRez=false;
if (rezPoint.x<Math.min(PHead1.x,PTail1.x)||rezPoint.x>Math.max(PHead1.x,PTail1.x))
bRez=false;
//по y
if (rezPoint.y<Math.min(PHead0.y,PTail0.y)||rezPoint.y>Math.max(PHead0.y,PTail0.y))
bRez=false;
if (rezPoint.y<Math.min(PHead1.y,PTail1.y)||rezPoint.y>Math.max(PHead1.y,PTail1.y))
bRez=false;
if (!bRez)
{
rezPoint.x=0;
rezPoint.y=0;
}
return rezPoint;
}
//Так как в replaceAll много заморочек с регулярными выражениями
public static String replaceAll(String txt, String val, String rep) {
if(txt==null || val==null || rep==null) return txt;
return txt.replace(val,rep);
/*while(true)
{
String tmpstr=txt.replace(val, rep);
if(tmpstr.equals(txt))
{
txt=tmpstr;
break;
}else
{
txt=tmpstr;
}
}
return txt;*/
}
public static byte[] subArray(byte[] b, int offset, int length) {
byte[] sub = new byte[length];
for (int i = offset; i < offset + length; i++) {
try {
sub[i - offset] = b[i];
} catch (Exception e) {
}
}
return sub;
}
}

View File

@ -0,0 +1,73 @@
package tools;
import com.google.android.gms.maps.model.LatLng;
import com.google.maps.android.clustering.ClusterItem;
public class ClusterMarker implements ClusterItem {
private LatLng position;
private String title;
private String snippet;
private int iconPicture;
public ClusterMarker(LatLng position, String title, String snipped, int iconPicture) {
this.position = position;
this.title = title;
this.snippet = snippet;
this.iconPicture = iconPicture;
}
public ClusterMarker() {
}
@Override
public LatLng getPosition() {
return position;
}
public void setPosition(LatLng position) {
this.position = position;
}
@Override
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
@Override
public String getSnippet() {
return snippet;
}
public void setSnippet(String snippet) {
this.snippet = snippet;
}
public int getIconPicture() {
return iconPicture;
}
public void setIconPicture(int iconPicture) {
this.iconPicture = iconPicture;
}
/*
@Override
public LatLng getPosition() {
return null;
}
@Override
public String getTitle() {
return null;
}
@Override
public String getSnippet() {
return null;
}*/
}

View File

@ -0,0 +1,6 @@
package tools;
public interface LatLonListener {
public double getLat();
public double getLon();
}

View File

@ -0,0 +1,54 @@
package tools;
import android.content.Context;
import android.graphics.Bitmap;
import android.view.ViewGroup;
import android.widget.ImageView;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.maps.android.clustering.Cluster;
import com.google.maps.android.clustering.ClusterManager;
import com.google.maps.android.clustering.view.DefaultClusterRenderer;
import com.google.maps.android.ui.IconGenerator;
public class MyClusterManagerRenderer extends DefaultClusterRenderer<ClusterMarker> {
private final IconGenerator iconGenerator;
private final ImageView imageView;
private final int markerWith;
private final int markerHeight;
public MyClusterManagerRenderer(Context context, GoogleMap map, ClusterManager<ClusterMarker> clusterManager) {
super(context, map, clusterManager);
//this.iconGenerator = iconGenerator;
//this.imageView = imageView;
//this.markerWith = markerWith;
//this.markerHeight = markerHeight;
iconGenerator = new IconGenerator(context.getApplicationContext());
imageView = new ImageView(context.getApplicationContext());
markerWith = (int) 40; //TODO брать из ресурсов
markerHeight = (int) 40; //TODO брать из ресурсов
imageView.setLayoutParams(new ViewGroup.LayoutParams(markerWith, markerHeight));
int pagging = (int) 5;
imageView.setPadding(pagging,pagging,pagging,pagging);
iconGenerator.setContentView(imageView);
}
@Override
protected void onBeforeClusterItemRendered(ClusterMarker item, MarkerOptions markerOptions) {
//super.onBeforeClusterItemRendered(item, markerOptions);
imageView.setImageResource(item.getIconPicture());
Bitmap icon = iconGenerator.makeIcon();
markerOptions.icon(BitmapDescriptorFactory.fromBitmap(icon))
.title(item.getTitle());
}
@Override
protected boolean shouldRenderAsCluster(Cluster<ClusterMarker> cluster) {
//return super.shouldRenderAsCluster(cluster);
return false; //Не объединаять точки в одну точку если они наплывают друг на друга.
}
}

View File

@ -0,0 +1,34 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportHeight="108"
android:viewportWidth="108">
<path
android:fillType="evenOdd"
android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
android:strokeColor="#00000000"
android:strokeWidth="1">
<aapt:attr name="android:fillColor">
<gradient
android:endX="78.5885"
android:endY="90.9159"
android:startX="48.7653"
android:startY="61.0927"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
android:strokeColor="#00000000"
android:strokeWidth="1" />
</vector>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Определение списка состояний -->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Задаем элемент списка и описываем состояние при помощи атрибутов. -->
<!-- android:drawable - позволяет указать на XML-файл, который определяет фигуру -->
<!-- android:state_focused="true" - указывает использовать данное состояние, когда объект в фокусе -->
<item android:drawable="@drawable/button_focused" android:state_focused="true"/>
<item android:drawable="@drawable/button_presed" android:state_pressed="true"/>
<item android:drawable="@drawable/button_normal"/>
</selector>

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Корневым элементом должен быть объект share (холс) -->
<!-- android:shape - задает форму кнопки. В нашем случаем форма кнопки - прямоугольник -->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<stroke
android:width="1px"
android:color="#BB000000" />
<!-- Устанавливаем значение радиуса скругления для всех углов прямоугольника -->
<corners android:radius="12px" />
<!-- Задаем линейный градиент для заливки прямоугольника -->
<gradient
android:angle="90"
android:endColor="@color/button_focused_color_end"
android:startColor="@color/button_focused_color_start"
android:type="linear" />
<!-- Задаем отступы текста кнопки относительно краев прямоугольника -->
<padding
android:bottom="9px"
android:left="6px"
android:right="6px"
android:top="9px" />
</shape>

View File

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<stroke
android:width="1px"
android:color="#BB000000" />
<corners android:radius="12px" />
<gradient
android:angle="90"
android:endColor="@color/button_normal_color_end"
android:startColor="@color/button_normal_color_start"
android:type="linear" />
<padding
android:bottom="9px"
android:left="6px"
android:right="6px"
android:top="9px" />
<!--
<solid android:color="#F000" />
<stroke
android:width="1px"
android:color="#BB000000" />
<padding
android:bottom="7dp"
android:left="10dp"
android:right="10dp"
android:top="7dp" />
<corners
android:bottomLeftRadius="5dp"
android:bottomRightRadius="5dp"
android:topLeftRadius="5dp"
android:topRightRadius="5dp" />
<gradient
android:angle="90"
android:centerColor="#5b5bcd"
android:endColor="#6f6fcf"
android:startColor="#4747e0"
android:type="linear" />
-->
</shape>

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<stroke
android:width="1px"
android:color="#BB000000" />
<corners android:radius="12px" />
<gradient
android:angle="270"
android:endColor="@color/button_pressed_color_end"
android:startColor="@color/button_pressed_color_start"
android:type="linear" />
<padding
android:bottom="9px"
android:left="6px"
android:right="6px"
android:top="9px" />
<!-- Толщина рамки прямоугольника -->
<stroke
android:width="2px"
android:color="#52B10C" />
</shape>

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<gradient
android:type="linear"
android:useLevel="true"
android:angle="45.0"
android:startColor="#fffc95"
android:endColor="#ffffff" />
</shape>
</item>
</selector>

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:viewportHeight="31.999998"
android:viewportWidth="31.999998" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#ffffff" android:pathData="M29.4296,7.2035L21.0928,7.2035L19.4094,4.3754C19.2447,4.0989 18.9467,3.9295 18.6249,3.9295l-5.2947,0c-0.3218,0 -0.6198,0.1694 -0.7844,0.4459L10.8624,7.2035L8.1267,7.2035l0,-0.6233c0,-0.5041 -0.4087,-0.9128 -0.9128,-0.9128L3.8362,5.6674c-0.5042,0 -0.9128,0.4087 -0.9128,0.9128l0,0.6233l-0.3976,0C1.2578,7.2035 0.2302,8.2313 0.2302,9.4989l0,16.6199c0,1.2678 1.0276,2.2955 2.2954,2.2955l26.904,0c1.2678,0 2.2955,-1.0277 2.2955,-2.2955L31.7251,9.4989C31.7252,8.2313 30.6973,7.2035 29.4296,7.2035ZM15.9776,24.3427c-3.6086,0 -6.5338,-2.9253 -6.5338,-6.5339 0,-3.6085 2.9253,-6.5338 6.5338,-6.5338 3.6086,0 6.5338,2.9254 6.5338,6.5338 0,3.6087 -2.9253,6.5339 -6.5338,6.5339zM27.9974,11.936l-2.8604,0c-0.5041,0 -0.9128,-0.4087 -0.9128,-0.913 0,-0.5042 0.4087,-0.913 0.9128,-0.913l2.8604,0c0.5043,0 0.913,0.4087 0.913,0.913 0,0.5042 -0.4087,0.913 -0.913,0.913z"/>
<path android:fillColor="#ffffff" android:pathData="M15.9776,17.8088m-4.5646,0a4.5646,4.5646 0,1 1,9.1291 0a4.5646,4.5646 0,1 1,-9.1291 0"/>
</vector>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="32dp"
android:height="32dp"
android:viewportWidth="32"
android:viewportHeight="32">
<path
android:pathData="M15.959,0.7593A15.1197,15.1197 0,1 1,5.2724 5.1874,15.0631 15.0631,0 0,1 15.959,0.7593ZM16.7364,14.334a1.7344,1.7344 0,0 1,0.7159 0.6741h2.4355a0.6667,0.6667 0,0 1,0.0836 -0.6593,0.6593 0.6593,0 0,1 0.9201,-0.1181l1.449,1.1193a0.6495,0.6495 0,0 1,0.246 0.5117v0,0.0148 0a0.6519,0.6519 0,0 1,-0.246 0.5142l-1.449,1.1169A0.6544,0.6544 0,0 1,19.8878 16.7498h-2.4379a1.7221,1.7221 0,1 1,-2.4601 -2.3002l0.0197,-3.331a0.6544,0.6544 0,0 1,-0.7626 -1.0111l1.1489,-1.4219a0.6568,0.6568 0,0 1,0.492 -0.246h0.0148a0.6519,0.6519 0,0 1,0.5412 0.2657l1.0849,1.4761a0.6544,0.6544 0,0 1,-0.77 0.9963zM22.1486,25.1436a0.738,0.738 0,0 1,-1.2596 0.738l-0.5437,-0.9398a0.738,0.738 0,0 1,1.2596 -0.738l0.5437,0.9422zM9.767,6.602A0.738,0.738 0,0 1,11.0266 5.8787L11.5702,6.8185A0.738,0.738 0,1 1,10.3107 7.5417ZM25.9544,20.8065a0.738,0.738 0,1 1,-0.7233 1.2596l-0.9398,-0.5437a0.738,0.738 0,0 1,0.7233 -1.2596zM5.9612,10.9416A0.738,0.738 0,1 1,6.6993 9.682L7.6415,10.2257A0.738,0.738 0,0 1,6.9035 11.4853ZM27.0835,15.1434a0.738,0.738 0,0 1,0 1.4588h-1.0874a0.738,0.738 0,0 1,0 -1.4588zM4.8345,16.6047a0.738,0.738 0,1 1,0 -1.4588h1.0874a0.738,0.738 0,0 1,0 1.4588zM25.2311,9.682a0.738,0.738 0,0 1,0.7233 1.2596l-0.9398,0.5437A0.738,0.738 0,0 1,24.2913 10.2257ZM6.687,22.0661A0.738,0.738 0,1 1,5.9637 20.8065l0.9398,-0.5437a0.738,0.738 0,0 1,0.7233 1.2596zM20.8915,5.8787a0.738,0.738 0,0 1,1.2596 0.7233L21.6074,7.5417A0.738,0.738 0,1 1,20.3478 6.8185ZM11.0266,25.8718A0.738,0.738 0,0 1,9.767 25.1338l0.5437,-0.9422a0.738,0.738 0,0 1,1.2596 0.738l-0.5437,0.9398zM15.2284,4.7495a0.738,0.738 0,0 1,1.4588 0v1.0874a0.738,0.738 0,0 1,-1.4588 0zM16.6872,26.9985a0.738,0.738 0,1 1,-1.4588 0L15.2284,25.9112a0.738,0.738 0,0 1,1.4588 0zM25.4451,6.3904a13.4099,13.4099 0,1 0,3.9361 9.4836,13.3755 13.3755,0 0,0 -3.9361,-9.4836z"
android:strokeWidth="0.24600846"
android:fillColor="#ffffff"/>
</vector>

View File

@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="32dp"
android:height="32dp"
android:viewportWidth="32"
android:viewportHeight="32">
<path
android:pathData="m7.231,30.6091c0,0.3724 0.3019,0.6742 0.6742,0.6742l17.1145,0c0.3724,0 0.6742,-0.3019 0.6742,-0.6742L25.694,8.7633L7.231,8.7633ZM20.2551,12.481l2.5284,0l0,14.6994l-2.5284,0zM15.1983,12.481l2.5284,0l0,14.6994l-2.5284,0zM10.1415,12.481l2.5284,0l0,14.6994l-2.5284,0z"
android:fillColor="#ffffff"/>
<path
android:pathData="M22.1455,4.0242L22.1455,1.6c0,-0.3724 -0.3019,-0.6742 -0.6742,-0.6742l-10.0175,0c-0.3724,0 -0.6742,0.3019 -0.6742,0.6742l0,2.4243 0,0.4214 0,0.4214L6.0666,4.867c-0.3724,0 -0.6742,0.3019 -0.6742,0.6742l0,1.705c0,0.3723 0.3019,0.6742 0.6742,0.6742l1.1644,0 18.463,0 1.1644,0c0.3724,0 0.6742,-0.3019 0.6742,-0.6742l0,-1.705c0,-0.3724 -0.3019,-0.6742 -0.6742,-0.6742L22.1455,4.867l0,-0.4214zM19.6171,4.7284L13.3079,4.7284L13.3079,4.4456 13.3079,4.0242 13.3079,3.4541l6.3092,0l0,0.5701 0,0.4214z"
android:fillColor="#ffffff"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="32dp"
android:height="32dp"
android:viewportWidth="32"
android:viewportHeight="32">
<path
android:pathData="m31.0136,15.0505c-0.0624,-0.1505 -0.1517,-0.2851 -0.2655,-0.3989l-3.6698,-3.6698c-0.4784,-0.4784 -1.2518,-0.4784 -1.7302,0 -0.4784,0.4784 -0.4784,1.2518 0,1.7302l1.5822,1.5822l-3.1644,0l0,-11.013C23.7658,2.6058 23.2188,2.0576 22.5421,2.0576L2.9635,2.0576C2.9194,2.0576 2.8802,2.076 2.8374,2.0809 2.7787,2.087 2.7273,2.0968 2.6711,2.1114 2.5438,2.1433 2.4276,2.1934 2.3198,2.262 2.2929,2.2791 2.2586,2.2803 2.2329,2.2999 2.2231,2.3073 2.2195,2.3208 2.2097,2.3281 2.0763,2.4333 1.965,2.5618 1.8842,2.7148c-0.0172,0.033 -0.0208,0.0685 -0.0342,0.1028 -0.0392,0.093 -0.082,0.1836 -0.0967,0.2863 -0.0061,0.0367 0.0049,0.071 0.0037,0.1065 -0.0012,0.0245 -0.0172,0.0465 -0.0172,0.071L1.7398,27.7547c0,0.5837 0.4124,1.0854 0.9838,1.1992l12.2367,2.4474c0.0796,0.0172 0.1603,0.0245 0.2398,0.0245 0.2802,0 0.5555,-0.0967 0.7758,-0.2778 0.2827,-0.2325 0.4479,-0.5788 0.4479,-0.9459L16.4238,28.9784L22.5421,28.9784c0.6767,0 1.2236,-0.5482 1.2236,-1.2236L23.7658,16.7417l3.1644,0l-1.5822,1.5822c-0.4784,0.4784 -0.4784,1.2518 0,1.7302 0.2386,0.2386 0.5519,0.3586 0.8652,0.3586 0.3133,0 0.6265,-0.1199 0.8652,-0.3586l3.6698,-3.6698c0.1138,-0.1138 0.2031,-0.2484 0.2655,-0.3989 0.1236,-0.2985 0.1236,-0.6362 0,-0.9348zM12.7161,20.71c-0.1395,0.5555 -0.6375,0.9263 -1.1857,0.9263 -0.0979,0 -0.1982,-0.011 -0.2974,-0.0367L8.7856,20.9877c-0.6559,-0.164 -1.0548,-0.8284 -0.8908,-1.4843 0.1627,-0.6546 0.8248,-1.0572 1.4831,-0.8896l2.4474,0.6119c0.6559,0.1639 1.0548,0.8284 0.8908,1.4843zM21.3185,26.531L16.4238,26.531L16.4238,6.9523c0,-0.5396 -0.3549,-1.0169 -0.8725,-1.1723L11.3015,4.505l10.017,0z"
android:fillColor="#ffffff"/>
</vector>

View File

@ -0,0 +1,7 @@
<vector android:height="48dp" android:viewportHeight="128"
android:viewportWidth="128" android:width="48dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#2d3e50"
android:pathData="M64.002,3.367c-25.749,0 -43.05,14.759 -43.05,36.725 0,29.112 37.015,81.601 37.383,82.011a7.603,7.603 0,0 0,11.323 0.006c0.374,-0.416 37.389,-52.905 37.389,-82.017C107.048,18.125 89.749,3.367 64.002,3.367ZM64,74.739a28.296,28.296 0,1 1,28.296 -28.296A28.296,28.296 0,0 1,64 74.739Z"
android:strokeColor="#ffc6ff" android:strokeWidth="3.8"/>
<path android:fillColor="#2e79bd" android:pathData="M82.842,58.572c-0.155,0.246 -0.31,0.474 -0.474,0.711a22.399,22.399 0,0 1,-36.733 0.009c-0.173,-0.237 -0.337,-0.483 -0.483,-0.729 0.018,-0.128 0.036,-0.246 0.055,-0.365a4.036,4.036 0,0 1,2.161 -2.908c3.765,-1.878 12.007,-4.641 12.007,-4.641v-2.726l-0.228,-0.173a7.862,7.862 0,0 1,-2.99 -5.005l-0.046,-0.292h-0.219a3.025,3.025 0,0 1,-2.817 -1.887,3.275 3.275,0 0,1 -0.419,-1.614 3.137,3.137 0,0 1,0.21 -1.121,1.584 1.584,0 0,1 0.611,-0.985l0.766,-0.456 -0.182,-0.821c-1.34,-5.862 3.045,-11.141 9.062,-11.515a0.519,0.519 0,0 1,0.119 -0.009c0.1,-0.009 0.201,-0.018 0.301,-0.018h0.912c0.1,0 0.201,0.009 0.301,0.018a0.519,0.519 0,0 1,0.119 0.009c6.026,0.374 10.412,5.653 9.071,11.515l-0.191,0.821 0.766,0.456a1.545,1.545 0,0 1,0.611 0.985,3.146 3.146,0 0,1 0.219,1.121 3.375,3.375 0,0 1,-0.419 1.614,3.025 3.025,0 0,1 -2.817,1.887h-0.219l-0.055,0.292a7.811,7.811 0,0 1,-2.981 5.005l-0.228,0.173v2.726s8.242,2.762 11.998,4.641a4.013,4.013 0,0 1,2.161 2.908C82.805,58.316 82.824,58.444 82.842,58.572Z"/>
</vector>

View File

@ -0,0 +1,170 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportHeight="108"
android:viewportWidth="108">
<path
android:fillColor="#26A69A"
android:pathData="M0,0h108v108h-108z" />
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
</vector>

View File

@ -0,0 +1,159 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="785.3449"
android:viewportHeight="785.3449">
<group android:translateX="20.625214"
android:translateY="-133.50864">
<path
android:pathData="m257.1,546.34c-3.28,15.34 -15.81,13.02 -26.88,5.45 -16.35,-14.29 -28.58,-39.03 -24.55,-55.27 3.14,-11.3 9.79,-23.69 30.36,-26.43 20.57,-2.74 27.38,3.48 47.32,16.79 75.83,-9.19 113.49,-5.37 159.82,3.04 46.33,8.41 98.43,18.37 138.21,53.93 -45.64,27.9 -95.41,34.09 -148.57,32.86 -53.16,-1.23 -93.35,-10.59 -130.71,-13.93 -25.58,8.98 -40,13.52 -59.29,20.54 -16.02,21.8 -41.43,21.07 -41.43,21.07"
android:strokeAlpha="1"
android:strokeLineJoin="miter"
android:strokeWidth="10"
android:fillColor="#00f700"
android:strokeColor="#00f500"
android:fillAlpha="1"
android:strokeLineCap="butt"/>
<path
android:pathData="m182.96,573.68c23.86,-0.63 34.35,-6.44 47.22,-21.21"
android:strokeAlpha="1"
android:strokeLineJoin="miter"
android:strokeWidth="10"
android:fillColor="#00f700"
android:strokeColor="#00f500"
android:fillAlpha="1"
android:strokeLineCap="butt"/>
<path
android:pathData="m177.85,405.55c25.32,22.16 42.3,41.73 53.6,65.6"
android:strokeAlpha="1"
android:strokeLineJoin="miter"
android:strokeWidth="10"
android:fillColor="#00f700"
android:strokeColor="#00f500"
android:fillAlpha="1"
android:strokeLineCap="butt"/>
<path
android:pathData="M234.67,498.86a6.94,4.92 90,1 0,9.85 0a6.94,4.92 90,1 0,-9.85 0z"
android:strokeAlpha="1"
android:strokeWidth="8.98230648"
android:fillColor="#00f700"
android:strokeColor="#00f500"
android:fillAlpha="1"/>
<path
android:pathData="m339.68,567.15c-9.47,6.94 -21.99,14.23 -30.45,21.18 20.2,14.35 8.08,26.64 -8.08,36.62"
android:strokeAlpha="1"
android:strokeLineJoin="miter"
android:strokeWidth="10"
android:fillColor="#00f700"
android:strokeColor="#00f500"
android:fillAlpha="1"
android:strokeLineCap="butt"/>
<path
android:pathData="m379.95,542.77c41.97,-39.14 93.07,-64.18 120.71,-72.86 5.56,41.41 7.25,105.83 6.07,136.07 -12.92,-7.77 -25.36,12.14 -39.82,13.93"
android:strokeAlpha="1"
android:strokeLineJoin="miter"
android:strokeWidth="10"
android:fillColor="#00f700"
android:strokeColor="#00f500"
android:fillAlpha="1"
android:strokeLineCap="butt"/>
<path
android:pathData="m410.27,485.23c19.01,-13.97 37.12,-21.06 50.02,-25.87 4.2,5.02 10.53,15.82 12.94,21.05"
android:strokeAlpha="1"
android:strokeLineJoin="miter"
android:strokeWidth="10"
android:fillColor="#00f700"
android:strokeColor="#00f500"
android:fillAlpha="1"
android:strokeLineCap="butt"/>
<path
android:pathData="m441.92,552.95c46.54,5.13 102.5,9.02 134.29,-5.98"
android:strokeAlpha="1"
android:strokeLineJoin="miter"
android:strokeWidth="10"
android:fillColor="#00f700"
android:strokeColor="#00f500"
android:fillAlpha="1"
android:strokeLineCap="butt"/>
<path
android:pathData="m513.7,571.16c10.54,10.18 23.11,27.08 30.89,38.21 11.43,-2.32 20.54,1.61 24.64,7.68"
android:strokeAlpha="1"
android:strokeLineJoin="miter"
android:strokeWidth="10"
android:fillColor="#00f700"
android:strokeColor="#00f500"
android:fillAlpha="1"
android:strokeLineCap="butt"/>
<path
android:pathData="m257.1,546.34c-3.28,15.34 -15.81,13.02 -26.88,5.45 -16.35,-14.29 -28.58,-39.03 -24.55,-55.27 3.14,-11.3 9.79,-23.69 30.36,-26.43 20.57,-2.74 27.38,3.48 47.32,16.79 75.83,-9.19 113.49,-5.37 159.82,3.04 46.33,8.41 98.43,18.37 138.21,53.93 -45.64,27.9 -95.41,34.09 -148.57,32.86 -53.16,-1.23 -93.35,-10.59 -130.71,-13.93 -25.58,8.98 -40,13.52 -59.29,20.54 -16.02,21.8 -41.43,21.07 -41.43,21.07"
android:strokeAlpha="1"
android:strokeLineJoin="miter"
android:strokeWidth="10"
android:fillColor="#00000000"
android:strokeColor="#000000"
android:strokeLineCap="butt"/>
<path
android:pathData="m182.96,573.68c23.86,-0.63 34.35,-6.44 47.22,-21.21"
android:strokeAlpha="1"
android:strokeLineJoin="miter"
android:strokeWidth="10"
android:fillColor="#00000000"
android:strokeColor="#000000"
android:strokeLineCap="butt"/>
<path
android:pathData="m177.85,405.55c25.32,22.16 42.3,41.73 53.6,65.6"
android:strokeAlpha="1"
android:strokeLineJoin="miter"
android:strokeWidth="10"
android:fillColor="#00000000"
android:strokeColor="#000000"
android:strokeLineCap="butt"/>
<path
android:fillColor="#FF000000"
android:pathData="M234.67,498.86a6.94,4.92 90,1 0,9.85 0a6.94,4.92 90,1 0,-9.85 0z"
android:strokeAlpha="1"
android:strokeWidth="8.98230648"
android:strokeColor="#000000"/>
<path
android:pathData="m339.68,567.15c-9.47,6.94 -21.99,14.23 -30.45,21.18 20.2,14.35 8.08,26.64 -8.08,36.62"
android:strokeAlpha="1"
android:strokeLineJoin="miter"
android:strokeWidth="10"
android:fillColor="#00000000"
android:strokeColor="#000000"
android:strokeLineCap="butt"/>
<path
android:pathData="m379.95,542.77c41.97,-39.14 93.07,-64.18 120.71,-72.86 5.56,41.41 7.25,105.83 6.07,136.07 -12.92,-7.77 -25.36,12.14 -39.82,13.93"
android:strokeAlpha="1"
android:strokeLineJoin="miter"
android:strokeWidth="10"
android:fillColor="#00000000"
android:strokeColor="#000000"
android:strokeLineCap="butt"/>
<path
android:pathData="m410.27,485.23c19.01,-13.97 37.12,-21.06 50.02,-25.87 4.2,5.02 10.53,15.82 12.94,21.05"
android:strokeAlpha="1"
android:strokeLineJoin="miter"
android:strokeWidth="10"
android:fillColor="#00000000"
android:strokeColor="#000000"
android:strokeLineCap="butt"/>
<path
android:pathData="m441.92,552.95c46.54,5.13 102.5,9.02 134.29,-5.98"
android:strokeAlpha="1"
android:strokeLineJoin="miter"
android:strokeWidth="10"
android:fillColor="#00000000"
android:strokeColor="#000000"
android:strokeLineCap="butt"/>
<path
android:pathData="m513.7,571.16c10.54,10.18 23.11,27.08 30.89,38.21 11.43,-2.32 20.54,1.61 24.64,7.68"
android:strokeAlpha="1"
android:strokeLineJoin="miter"
android:strokeWidth="10"
android:fillColor="#00000000"
android:strokeColor="#000000"
android:strokeLineCap="butt"/>
</group>
</vector>

View File

@ -0,0 +1,14 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="32dp"
android:height="32dp"
android:viewportWidth="32"
android:viewportHeight="32">
<path
android:pathData="M16.1186,15.8814m-5.6475,0a5.6475,5.6475 0,1 1,11.2949 0a5.6475,5.6475 0,1 1,-11.2949 0"
android:strokeWidth="1.4118644"
android:fillColor="#fffffd"/>
<path
android:pathData="M17.5305,4.6839V1.7627H14.7068V4.6839C9.6085,5.3234 5.5621,9.3712 4.9211,14.4695H2v2.8237h2.9211c0.641,5.0982 4.686,9.1461 9.7856,9.7856V30h2.8237v-2.9211c5.0982,-0.6396 9.1461,-4.686 9.7856,-9.7856h2.9211V14.4695H27.3161C26.6766,9.3712 22.6288,5.3234 17.5305,4.6839ZM16.1186,24.3525c-4.6719,0 -8.4712,-3.7993 -8.4712,-8.4712 0,-4.6719 3.7993,-8.4712 8.4712,-8.4712 4.6719,0 8.4712,3.7993 8.4712,8.4712 0,4.6719 -3.7993,8.4712 -8.4712,8.4712z"
android:strokeWidth="1.4118644"
android:fillColor="#fffffd"/>
</vector>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="32dp"
android:height="32dp"
android:viewportWidth="32"
android:viewportHeight="32">
<path
android:pathData="m24.9492,4.6447c-2.4773,0 -4.485,2.0078 -4.485,4.485 0,0.6693 0.1472,1.3052 0.41,1.8746l4.075,7.9924 4.0751,-7.9925c0.2628,-0.5694 0.4099,-1.2053 0.4099,-1.8746 0,-2.4772 -2.0077,-4.485 -4.485,-4.485zM24.9492,11.8207c-1.4857,0 -2.691,-1.2053 -2.691,-2.691 0,-1.4857 1.2053,-2.691 2.691,-2.691 1.4857,0 2.691,1.2053 2.691,2.691 0,1.4857 -1.2053,2.691 -2.691,2.691zM26.2912,20.3124 L27.924,23.5763 23.7841,25.6454 22.3966,18.7041 22.6296,18.4711 22.6541,18.4465 21.7992,16.7647 21.3611,17.2027 15.9791,13.6147 10.5971,17.2027 7.0091,13.6147 1.6271,24.3787 8.8031,27.9667 15.9791,24.3787 23.1552,27.9667 30.3312,24.3787 27.3038,18.3257zM8.1724,25.6454 L4.0343,23.5763 7.4997,16.6421l1.829,1.829 0.233,0.233zM15.0821,22.8212 L10.0645,25.33 11.361,18.8495 11.5922,18.6953 15.0821,16.3687zM16.8761,22.8212v-6.4525l3.4899,2.3266 0.2295,0.1542 1.2964,6.4805z"
android:strokeWidth="0.05606258"
android:fillColor="#ffffff"/>
</vector>

View File

@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="32dp"
android:height="32dp"
android:viewportWidth="32"
android:viewportHeight="32">
<path
android:pathData="M29.7165,4.6196L2.3364,4.6196C1.2564,4.6196 0.3807,5.4952 0.3807,6.5753l0,19.5572c0,1.08 0.8757,1.9557 1.9557,1.9557l27.3801,0c1.08,0 1.9557,-0.8757 1.9557,-1.9557L31.6723,6.5753C31.6723,5.4952 30.7966,4.6196 29.7165,4.6196ZM27.7608,8.531L27.7608,20.1665L22.6576,13.7875c-0.1824,-0.2282 -0.4574,-0.3629 -0.7497,-0.3672 -0.2903,-0.0062 -0.5711,0.1217 -0.7592,0.3448l-5.4088,6.3633 -2.989,-2.5611c-0.3457,-0.2956 -0.848,-0.3146 -1.2147,-0.0463L4.2921,22.8335L4.2921,8.531Z"
android:fillColor="#ffffff"/>
<path
android:pathData="M10.1593,12.4425m-1.9557,0a1.9557,1.9557 0,1 1,3.9114 0a1.9557,1.9557 0,1 1,-3.9114 0"
android:fillColor="#ffffff"/>
</vector>

View File

@ -0,0 +1,21 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="32dp"
android:height="32dp"
android:viewportWidth="32"
android:viewportHeight="32">
<path
android:pathData="M18.0222,4.6525l3.5593,0l0,5.9322l-3.5593,0z"
android:fillColor="#ffffff"/>
<path
android:pathData="M25.3865,1.6864L2.0053,1.6864l0,29.0678l28.4746,0L30.4799,6.7798ZM7.9375,2.8729l15.4237,0l0,9.4915l-15.4237,0zM25.1409,29.5678L6.7511,29.5678L6.7511,17.1102l18.3898,0z"
android:fillColor="#ffffff"/>
<path
android:pathData="m9.7172,20.6695l4.1525,0c0.3281,0 0.5932,-0.2652 0.5932,-0.5932 0,-0.3281 -0.2652,-0.5932 -0.5932,-0.5932l-4.1525,0c-0.3281,0 -0.5932,0.2652 -0.5932,0.5932 0,0.3281 0.2652,0.5932 0.5932,0.5932z"
android:fillColor="#ffffff"/>
<path
android:pathData="m9.7172,23.0424l5.9322,0c0.3281,0 0.5932,-0.2652 0.5932,-0.5932 0,-0.3281 -0.2652,-0.5932 -0.5932,-0.5932l-5.9322,0c-0.3281,0 -0.5932,0.2652 -0.5932,0.5932 0,0.3281 0.2652,0.5932 0.5932,0.5932z"
android:fillColor="#ffffff"/>
<path
android:pathData="m17.429,23.0424c0.1602,0 0.3085,-0.0653 0.4212,-0.172 0.1068,-0.1127 0.172,-0.2669 0.172,-0.4212 0,-0.1542 -0.0653,-0.3091 -0.172,-0.4212 -0.2195,-0.2195 -0.6169,-0.2195 -0.8364,0 -0.1127,0.1121 -0.178,0.2604 -0.178,0.4212 0,0.1602 0.0647,0.3085 0.172,0.4212 0.1121,0.1068 0.2604,0.172 0.4212,0.172z"
android:fillColor="#ffffff"/>
</vector>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="10dp"
android:height="10dp"
android:viewportWidth="10"
android:viewportHeight="10">
<path
android:pathData="M9.8912,3.5877A0.4107,0.4107 0,0 0,9.5117 3.3341H6.5107L5.3789,0.3149a0.4107,0.4107 0,0 0,-0.7692 0L3.4769,3.3341H0.4757A0.4107,0.4107 0,0 0,0.1854 4.0353L2.4853,6.3353 1.7208,9.3953A0.4109,0.4109 0,0 0,2.3575 9.8289L4.9938,7.9461 7.6301,9.8289A0.4109,0.4109 0,0 0,8.2668 9.3953L7.5023,6.3353 9.8022,4.0353a0.4107,0.4107 0,0 0,0.089 -0.4476z"
android:strokeWidth="0.01925288"
android:fillColor="#a60000"/>
</vector>

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<size
android:width="@dimen/spacing_medium"
android:height="@dimen/spacing_medium" />
<solid android:color="@android:color/transparent" />
</shape>

Binary file not shown.

After

Width:  |  Height:  |  Size: 228 KiB

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,83 @@
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:baselineAligned="false"
android:divider="@drawable/spacer_medium"
android:showDividers="middle"
android:paddingLeft="@dimen/activity_horizontal_margin"
>
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
app:boxBackgroundColor="@color/transparent"
android:background="@color/transparent">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/edtLat"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/transparent"
android:enabled="false"
android:hint="@string/Lat"
android:maxLines="1"
android:singleLine="true"/>
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
app:boxBackgroundColor="@color/transparent"
android:background="@color/transparent">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/edtLon"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/transparent"
android:enabled="false"
android:hint="@string/Lon"
android:maxLines="1"
android:singleLine="true" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.button.MaterialButton
android:id="@+id/btnGetGPS"
style="@style/Widget.MaterialComponents.Button.Icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:icon="@drawable/ic_location"
app:iconSize="24dp"
android:minWidth="40dp"
app:iconPadding="0dp"
android:insetLeft="0dp"
android:insetTop="0dp"
android:insetRight="0dp"
android:insetBottom="0dp"
app:iconGravity="textStart"
/>
<com.google.android.material.button.MaterialButton
android:id="@+id/btnDelGPS"
style="@style/Widget.MaterialComponents.Button.Icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:icon="@drawable/ic_delete"
app:iconSize="24dp"
android:minWidth="40dp"
app:iconPadding="0dp"
android:insetLeft="0dp"
android:insetTop="0dp"
android:insetRight="0dp"
android:insetBottom="0dp"
app:iconGravity="textStart"
/>
</LinearLayout>
</FrameLayout>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,78 @@
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="@drawable/spacer_medium"
android:showDividers="middle">
<TextView
android:id="@+id/tvLat"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/Lat"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textStyle="bold" />
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/edtLat"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10"
android:enabled="false"
android:inputType="numberDecimal" />
<TextView
android:id="@+id/tvLon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/Lon"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textStyle="bold" />
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/edtLon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10"
android:enabled="false"
android:inputType="numberDecimal" />
<com.google.android.material.button.MaterialButton
android:id="@+id/btnGetGPS"
style="@style/Widget.MaterialComponents.Button.Icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:insetLeft="0dp"
android:insetTop="0dp"
android:insetRight="0dp"
android:insetBottom="0dp"
android:minWidth="40dp"
app:icon="@drawable/ic_location"
app:iconGravity="textStart"
app:iconPadding="0dp"
app:iconSize="24dp" />
<com.google.android.material.button.MaterialButton
android:id="@+id/btnDelGPS"
style="@style/Widget.MaterialComponents.Button.Icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:insetLeft="0dp"
android:insetTop="0dp"
android:insetRight="0dp"
android:insetBottom="0dp"
android:minWidth="40dp"
app:icon="@drawable/ic_delete"
app:iconGravity="textStart"
app:iconPadding="0dp"
app:iconSize="24dp" />
</LinearLayout>
</FrameLayout>

View File

@ -0,0 +1,17 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:background="@drawable/gradient_example"
tools:context=".ImagePickActivity" >
<!--TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" /-->
</RelativeLayout>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/gradient_example"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".LocustDelListActivity" >
<LinearLayout
android:id="@+id/linearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Spinner
android:id="@+id/spiList"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<ScrollView
android:id="@+id/scrollView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true" >
<LinearLayout
android:id="@+id/llList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button
android:id="@+id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/star" />
</LinearLayout>
</ScrollView>
</LinearLayout>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/btnAdd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="@dimen/fab_margin"
app:backgroundTint="@color/button_normal_color_start"
app:srcCompat="@android:drawable/ic_input_add"
app:tint="@android:color/white"
/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -0,0 +1,59 @@
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/gradient_example"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".LocustListActivity" >
<LinearLayout
android:id="@+id/linearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Spinner
android:id="@+id/spiList"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<ScrollView
android:id="@+id/scrollView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true" >
<LinearLayout
android:id="@+id/llList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button
android:id="@+id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/star" />
</LinearLayout>
</ScrollView>
</LinearLayout>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/btnAdd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="@dimen/fab_margin"
app:backgroundTint="@color/button_normal_color_start"
app:srcCompat="@android:drawable/ic_input_add"
app:tint="@android:color/white"
/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -0,0 +1,178 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp"
android:background="@drawable/gradient_example"
tools:context=".MainActivity" >
<LinearLayout
android:id="@+id/pBar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:orientation="vertical">
<Space
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"/>
<TextView
android:id="@+id/tvProgressInfo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:gravity="center"
android:text="Synchronize directories through the Internet!"
android:textAlignment="center"
android:textAppearance="?android:attr/textAppearanceMedium"/>
<ProgressBar
android:id="@+id/progress"
style="?android:attr/progressBarStyleLarge"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"/>
<TextView
android:id="@+id/tvCountTasks"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:gravity="center"
android:text="@string/action_synchronize"
android:textAlignment="center"
android:textAppearance="?android:attr/textAppearanceMedium"/>
<Space
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"/>
</LinearLayout>
<LinearLayout
android:id="@+id/form"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:visibility="gone"
android:orientation="vertical">
<TextView
android:id="@+id/textView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:gravity="center"
android:text="@string/Fields_marked_are_mandatory"
android:textAlignment="center"
android:textAppearance="?android:attr/textAppearanceMedium"/>
<Space
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"/>
<Button
android:id="@+id/btnLocust"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginBottom="62dp"
android:layout_marginLeft="62dp"
android:layout_marginRight="62dp"
android:minHeight="70dp"
android:text="@string/title_activity_locust"/>
<Button
android:id="@+id/btnLocustDel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="62dp"
android:layout_marginRight="62dp"
android:minHeight="70dp"
android:text="@string/title_activity_locust_del"/>
<Button
android:id="@+id/btnSetup"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="52dp"
android:layout_marginLeft="62dp"
android:layout_marginRight="62dp"
android:minHeight="70dp"
android:text="@string/title_activity_setup"/>
<Space
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignRight="@+id/textView1"
android:layout_marginBottom="46dp">
<Space
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"/>
<TextView
android:id="@+id/tvV"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Version: "
android:textAppearance="?android:attr/textAppearanceMedium"/>
<TextView
android:id="@+id/tvVersion"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/textView1"
android:layout_alignParentBottom="true"
android:layout_alignRight="@+id/textView1"
android:layout_marginBottom="16dp">
<Space
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"/>
<TextView
android:id="@+id/tvID"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/Application_ID"
android:textAppearance="?android:attr/textAppearanceMedium"/>
<TextView
android:id="@+id/tvAndroidID"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"/>
</LinearLayout>
</LinearLayout>
</RelativeLayout>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MapsActivity" />

View File

@ -0,0 +1,102 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/gradient_example"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".LocustDelListActivity" >
<LinearLayout
android:id="@+id/linearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<!--?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/gradient_example"
android:padding="@dimen/activity_horizontal_margin"-->
<TextView
android:id="@+id/tvUpdate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:textAlignment="center"
android:text="@string/Please_update_your_phone_tablet"
android:textStyle="bold"
android:textSize="@dimen/font_size"/>
<Space
android:id="@+id/sUpdate"
android:layout_width="match_parent"
android:layout_height="40dp" />
<SurfaceView
android:id="@+id/surfaceView"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_centerVertical="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/Country"
android:textStyle="bold"
android:textSize="@dimen/font_size"/>
<TextView
android:id="@+id/tvCountry"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
android:textSize="@dimen/font_size"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/Organization"
android:textStyle="bold"
android:textSize="@dimen/font_size"/>
<TextView
android:id="@+id/tvOrganization"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
android:textSize="@dimen/font_size"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/Responsible_person_inspector"
android:textStyle="bold"
android:textSize="@dimen/font_size"/>
<TextView
android:id="@+id/tvName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
android:textSize="@dimen/font_size"/>
</LinearLayout>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/btnOpen"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="@dimen/fab_margin"
app:backgroundTint="@color/button_normal_color_start"
app:srcCompat="@android:drawable/ic_menu_gallery"
app:tint="@android:color/white"
/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -0,0 +1,225 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/gradient_example"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:configChanges = "orientation|keyboard"
tools:context=".SetupActivity" >
<ScrollView
android:id="@+id/scrollView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/scrollView1"
android:layout_below="@+id/scrollView1"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<Button
android:id="@+id/btnSynchronization"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:minHeight="40dp"
android:minWidth="120dp"
android:text="@string/action_synchronize" />
<TextView
android:id="@+id/tvSynchronization"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/action_synchronize"
android:textAppearance="?android:attr/textAppearanceMedium"/>
</LinearLayout>
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/To_change_the_language_you_need_to_restart_the_application"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TableLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/btnAz"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:minWidth="190dp"
android:minHeight="40dp"
android:layout_margin="2dp"
android:text="@string/Azerbaijani" />
<Button
android:id="@+id/btnAr"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:minWidth="190dp"
android:minHeight="40dp"
android:layout_margin="2dp"
android:text="@string/Armenia" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/btnEn"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:minWidth="190dp"
android:minHeight="40dp"
android:layout_margin="2dp"
android:text="@string/English" />
<Button
android:id="@+id/btnGr"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:minWidth="190dp"
android:minHeight="40dp"
android:layout_margin="2dp"
android:text="@string/Georgian" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/btnKz"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:minWidth="190dp"
android:minHeight="40dp"
android:layout_margin="2dp"
android:text="@string/Kazakh" />
<Button
android:id="@+id/btnKg"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:minWidth="190dp"
android:minHeight="40dp"
android:layout_margin="2dp"
android:text="@string/Kyrgyz" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/btnDr"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:minWidth="190dp"
android:minHeight="40dp"
android:layout_margin="2dp"
android:text="@string/Afghan" />
<Button
android:id="@+id/btnRu"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:minWidth="190dp"
android:minHeight="40dp"
android:layout_margin="2dp"
android:text="@string/Russian" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/btnTj"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:minWidth="190dp"
android:minHeight="40dp"
android:layout_margin="2dp"
android:text="@string/Tajik" />
<Button
android:id="@+id/btnTm"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:minWidth="190dp"
android:minHeight="40dp"
android:layout_margin="2dp"
android:text="@string/Turkman" />
</TableRow>
</TableLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="0.05"
android:orientation="horizontal">
<Button
android:id="@+id/btnUz"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:minWidth="190dp"
android:minHeight="40dp"
android:layout_margin="2dp"
android:text="@string/Uzbek" />
</LinearLayout>
<Space
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minHeight="10dp"
android:minWidth="10dp" />
<CheckBox
android:id="@+id/cbIdentifyCountryRegion"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/Identify_country_region" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="0.05"
android:orientation="horizontal">
<Button
android:id="@+id/btnQR"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:minWidth="190dp"
android:minHeight="40dp"
android:layout_margin="2dp"
android:text="@string/Authorize_the_tablet_by_QR_code" />
</LinearLayout>
</LinearLayout>
</ScrollView>
</RelativeLayout>

View File

@ -0,0 +1,18 @@
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="14dp"
android:text="TextView"
android:textSize="16sp"
android:textColor="#000000"
/>
<!--androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
</androidx.constraintlayout.widget.ConstraintLayout-->

View File

@ -0,0 +1,93 @@
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:paddingLeft="@dimen/activity_horizontal_margin">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:baselineAligned="false"
android:divider="@drawable/spacer_medium"
android:showDividers="middle">
<com.google.android.material.textfield.TextInputLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@color/transparent"
app:boxBackgroundColor="@color/transparent">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/edtLat"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/transparent"
android:enabled="false"
android:hint="@string/Lat"
android:inputType="numberDecimal"
android:maxLines="1"
android:singleLine="true" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@color/transparent"
app:boxBackgroundColor="@color/transparent">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/edtLon"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/transparent"
android:enabled="false"
android:hint="@string/Lon"
android:inputType="numberDecimal"
android:maxLines="1"
android:singleLine="true" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.button.MaterialButton
android:id="@+id/btnGetGPS"
style="@style/Widget.MaterialComponents.Button.Icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:insetLeft="0dp"
android:insetTop="0dp"
android:insetRight="0dp"
android:insetBottom="0dp"
android:minWidth="40dp"
app:icon="@drawable/ic_location"
app:iconGravity="textStart"
app:iconPadding="0dp"
app:iconSize="24dp" />
<com.google.android.material.button.MaterialButton
android:id="@+id/btnDelGPS"
style="@style/Widget.MaterialComponents.Button.Icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:insetLeft="0dp"
android:insetTop="0dp"
android:insetRight="0dp"
android:insetBottom="0dp"
android:minWidth="40dp"
app:icon="@drawable/ic_delete"
app:iconGravity="textStart"
app:iconPadding="0dp"
app:iconSize="24dp" />
</LinearLayout>
</LinearLayout>
</FrameLayout>

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:background="#000000" >
<ImageView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="fitCenter"
android:src="@drawable/splash" />
</LinearLayout>

View File

@ -0,0 +1,9 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/action_settings"
android:orderInCategory="100"
android:showAsAction="never"
android:title="@string/action_settings"/>
</menu>

View File

@ -0,0 +1,9 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/action_settings"
android:orderInCategory="100"
android:showAsAction="never"
android:title="@string/action_settings"/>
</menu>

View File

@ -0,0 +1,15 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- item
android:id="@+id/itemFoto"
android:orderInCategory="100"
android:showAsAction="never"
android:title="@string/action_foto"/-->
<item
android:id="@+id/action_settings"
android:orderInCategory="100"
android:showAsAction="never"
android:title="@string/action_settings"/>
</menu>

View File

@ -0,0 +1,9 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/action_settings"
android:orderInCategory="100"
android:showAsAction="never"
android:title="@string/action_settings"/>
</menu>

View File

@ -0,0 +1,21 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/itemCreate"
android:orderInCategory="100"
android:showAsAction="never"
android:title="@string/action_add"/>
<item
android:id="@+id/itemDelete"
android:orderInCategory="101"
android:showAsAction="never"
android:title="@string/action_delete"/>
<!-- item
android:id="@+id/itemExport"
android:orderInCategory="101"
android:showAsAction="never"
android:title="@string/action_export"/-->
</menu>

View File

@ -0,0 +1,21 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/itemCreate"
android:orderInCategory="100"
android:showAsAction="never"
android:title="@string/action_add"/>
<item
android:id="@+id/itemDelete"
android:orderInCategory="101"
android:showAsAction="never"
android:title="@string/action_delete"/>
<!--item
android:id="@+id/itemExport"
android:orderInCategory="102"
android:showAsAction="never"
android:title="@string/action_export"/-->
</menu>

View File

@ -0,0 +1,9 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/itemSettings"
android:orderInCategory="100"
android:showAsAction="never"
android:title="@string/action_settings"/>
</menu>

View File

@ -0,0 +1,9 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/itemSettings"
android:orderInCategory="100"
android:showAsAction="never"
android:title="@string/action_settings"/>
</menu>

View File

@ -0,0 +1,9 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/action_settings"
android:orderInCategory="100"
android:showAsAction="never"
android:title="@string/action_settings"/>
</menu>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Some files were not shown because too many files have changed in this diff Show More