Migrate to Android X

Update some Dependencies
Logo Added
Start and Stop Tracking Button
Optimize Code
Stable Version
This commit is contained in:
Supan Adit Pratama 2020-01-03 22:13:00 +07:00
parent 9aa6666d77
commit 3ead80b465
16 changed files with 181 additions and 96 deletions

View File

@ -44,7 +44,7 @@ android {
targetSdkVersion 28 targetSdkVersion 28
versionCode flutterVersionCode.toInteger() versionCode flutterVersionCode.toInteger()
versionName flutterVersionName versionName flutterVersionName
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
} }
buildTypes { buildTypes {
@ -64,8 +64,8 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.google.firebase:firebase-analytics:17.2.0' implementation 'com.google.firebase:firebase-analytics:17.2.0'
testImplementation 'junit:junit:4.12' testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0'
} }
apply plugin: 'com.google.gms.google-services' apply plugin: 'com.google.gms.google-services'

View File

@ -12,11 +12,11 @@
<application <application
android:name="io.flutter.app.FlutterApplication" android:name="io.flutter.app.FlutterApplication"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
android:label="Geo Smart App" android:label="@string/app_name"
android:usesCleartextTraffic="true"> android:usesCleartextTraffic="true">
<meta-data <meta-data
android:name="com.google.android.geo.API_KEY" android:name="com.google.android.geo.API_KEY"
android:value="AIzaSyCjhBV5aq1gsTCYsr6QCCxYusFlBa3DEMs" /> android:value="@string/api_key" />
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Geo Smart App</string>
<string name="api_key">AIzaSyCjhBV5aq1gsTCYsr6QCCxYusFlBa3DEMs</string>
</resources>

View File

@ -1,3 +1,5 @@
org.gradle.jvmargs=-Xmx1536M org.gradle.jvmargs=-Xmx1536M
android.enableR8=true android.enableR8=true
android.useAndroidX=true
android.enableJetifier=true

BIN
assets/images/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -27,6 +27,7 @@ class SettingBloc {
SharedPreferences sharedPreferences = await this.getSharedPreferences(); SharedPreferences sharedPreferences = await this.getSharedPreferences();
_subject.sink.add(new SettingModel( _subject.sink.add(new SettingModel(
sharedPreferences.getString(_host), sharedPreferences.getString(_host),
sharedPreferences.getString(_id),
)); ));
} }

View File

@ -1,3 +1,4 @@
class Config { class Config {
static const String api = "http://192.168.1.6:8080"; static const String api = "http://192.168.1.7:8080";
static const bool dynamicHostSetting = false;
} }

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:geo_app/page/startup.dart'; import 'package:geo_app/page/startup.dart';
void main() => runApp(MyApp()); void main() => runApp(MyApp());
@ -6,6 +7,7 @@ void main() => runApp(MyApp());
class MyApp extends StatelessWidget { class MyApp extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setEnabledSystemUIOverlays([]);
return MaterialApp( return MaterialApp(
title: 'Geo Smart App', title: 'Geo Smart App',
theme: ThemeData( theme: ThemeData(

View File

@ -7,6 +7,10 @@ class ResponseModel {
status = json['status']; status = json['status'];
} }
ResponseModel.fromNull() {
status = "Error";
}
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>(); final Map<String, dynamic> data = new Map<String, dynamic>();
data['status'] = this.status; data['status'] = this.status;

View File

@ -2,5 +2,19 @@ class SettingModel {
String host = ""; String host = "";
String id = ""; String id = "";
SettingModel(this.host); SettingModel(this.host, this.id);
bool isNullHost() {
return (this.host == "" || this.host == null);
}
bool isNullId() {
return (this.id == "" || this.id == null);
}
bool isNullHostId(String operator) {
return (operator == "and")
? isNullHost() && isNullId()
: isNullHost() || isNullId();
}
} }

View File

@ -5,9 +5,8 @@ import 'package:flutter/material.dart';
import 'package:geo_app/bloc/position_bloc.dart'; import 'package:geo_app/bloc/position_bloc.dart';
import 'package:geo_app/bloc/setting.dart'; import 'package:geo_app/bloc/setting.dart';
import 'package:geo_app/model/position.dart'; import 'package:geo_app/model/position.dart';
import 'package:geo_app/page/setting.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:flutter_background_geolocation/flutter_background_geolocation.dart'
as bg;
class Map extends StatefulWidget { class Map extends StatefulWidget {
Map({Key key, this.title}) : super(key: key); Map({Key key, this.title}) : super(key: key);
@ -33,10 +32,23 @@ class _MapState extends State<Map> {
String id; String id;
String host; String host;
bool isGranted = false;
bool isTracking = false;
@override @override
void initState() { void initState() {
BackgroundLocation.startLocationService();
super.initState(); super.initState();
BackgroundLocation.checkPermissions();
BackgroundLocation.getPermissions(
onDenied: () {
isGranted = false;
print("Denied");
},
onGranted: () {
isGranted = true;
print("Granted");
},
);
_settingBloc = new SettingBloc(); _settingBloc = new SettingBloc();
_settingBloc.getSetting(); _settingBloc.getSetting();
@ -45,51 +57,65 @@ class _MapState extends State<Map> {
this.id = settingModel.id; this.id = settingModel.id;
this.host = settingModel.host; this.host = settingModel.host;
if (settingModel.isNullId()) {
Navigator.of(context).pushReplacement(new MaterialPageRoute(
builder: (BuildContext context) => Setting(),
));
}
if (this.host != null && this.host != "") { if (this.host != null && this.host != "") {
setState(() { setState(() {
_positionBloc = new PositionBloc(settingModel); _positionBloc = new PositionBloc(settingModel);
}); });
} }
}); });
bg.BackgroundGeolocation.onLocation((bg.Location location) {
print('[location] - $location');
});
bg.BackgroundGeolocation.ready(
bg.Config(
desiredAccuracy: bg.Config.DESIRED_ACCURACY_HIGH,
distanceFilter: 10.0,
stopOnTerminate: false,
startOnBoot: true,
debug: true,
logLevel: bg.Config.LOG_LEVEL_VERBOSE),
).then((bg.State state) {
if (!state.enabled) {
bg.BackgroundGeolocation.start();
}
});
BackgroundLocation.getLocationUpdates((location) async {
print("Location Update");
setState(() {
this.latitude = location.latitude;
this.longitude = location.longitude;
this.accuracy = location.accuracy;
this.altitude = location.altitude;
this.bearing = location.bearing;
this.speed = location.speed;
if (this._position != null) { BackgroundLocation.getLocationUpdates((location) async {
if (this._position.isValid()) { if (!isTracking) {
print("VALID"); this.isTracking = true;
if (_positionBloc != null) { }
print("SEND"); if (!isGranted) {
_positionBloc.sendPosition( this.isGranted = true;
this._position.lat.toString(), }
this._position.lng.toString(), print("Location Updated");
); this.latitude = location.latitude;
} this.longitude = location.longitude;
this.accuracy = location.accuracy;
this.altitude = location.altitude;
this.bearing = location.bearing;
this.speed = location.speed;
if (this.id != null) {
this._position = Position(
id: this.id,
lat: this.latitude.toString(),
lng: this.longitude.toString(),
type: "user",
);
} else {
BackgroundLocation.stopLocationService();
Navigator.of(context).pushReplacement(new MaterialPageRoute(
builder: (BuildContext context) => Setting(),
));
}
if (this._position != null) {
if (this._position.isValid()) {
print("Valid Position");
if (_positionBloc != null) {
print("Send Position " +
this._position.lat.toString() +
", " +
this._position.lng.toString());
_positionBloc.sendPosition(
this._position.lat.toString(),
this._position.lng.toString(),
);
} }
} else {
print("Invalid Position");
} }
}); }
}); });
} }
@ -110,17 +136,51 @@ class _MapState extends State<Map> {
myLocationButtonEnabled: true, myLocationButtonEnabled: true,
onMapCreated: (GoogleMapController controller) { onMapCreated: (GoogleMapController controller) {
_controller.complete(controller); _controller.complete(controller);
print("Map Created");
}, },
), ),
Container(
child: Image.asset("assets/images/logo.png"),
width: 70,
height: 70,
alignment: Alignment.topLeft,
margin: EdgeInsets.only(left: 10.0),
),
Container(
child: FlatButton(
color: (isTracking) ? Colors.redAccent : Colors.green,
onPressed: toggleTracking,
child: Text(
(isTracking) ? "Stop Tracking" : "Start Tracking",
style: TextStyle(color: Colors.white),
),
),
margin: EdgeInsets.only(bottom: 50.0),
alignment: Alignment.bottomCenter,
)
], ],
), ),
); );
} }
toggleTracking() {
if (isGranted) {
if (isTracking) {
BackgroundLocation.stopLocationService();
} else {
BackgroundLocation.startLocationService();
}
setState(() {
isTracking = !isTracking;
});
} else {
print("Access Denied");
}
}
@override @override
void dispose() { void dispose() {
BackgroundLocation.stopLocationService(); print("Disposed");
super.dispose(); super.dispose();
BackgroundLocation.stopLocationService();
} }
} }

View File

@ -2,6 +2,7 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:geo_app/bloc/setting.dart'; import 'package:geo_app/bloc/setting.dart';
import 'package:geo_app/bloc/unique_id_bloc.dart'; import 'package:geo_app/bloc/unique_id_bloc.dart';
import 'package:geo_app/config.dart';
import 'package:geo_app/model/setting.dart'; import 'package:geo_app/model/setting.dart';
import 'package:geo_app/page/map.dart'; import 'package:geo_app/page/map.dart';
@ -25,23 +26,39 @@ class _SettingState extends State<Setting> {
_settingBloc.getSetting(); _settingBloc.getSetting();
if (!Config.dynamicHostSetting) {
_settingBloc.setSetting(new SettingModel(Config.api, null));
}
_settingBloc.subject.listen((settingModel) { _settingBloc.subject.listen((settingModel) {
this.id = settingModel.id; if (!settingModel.isNullId()) {
this.host = settingModel.host; this.id = settingModel.id;
}
if (!settingModel.isNullHost()) {
this.host = settingModel.host;
}
_hostController.text = this.host; _hostController.text = this.host;
if (this.host != null && this.host != "") { if (settingModel.isNullId()) {
print("Requesting Unique ID");
_uniqueIDBloc = new UniqueIDBloc(settingModel); _uniqueIDBloc = new UniqueIDBloc(settingModel);
_uniqueIDBloc.getUniqueID(); _uniqueIDBloc.getUniqueID();
} }
if (_uniqueIDBloc != null) { if (_uniqueIDBloc != null) {
this._uniqueIDBloc.subject.listen((uniqueId) { this._uniqueIDBloc.subject.listen((uniqueId) {
print("Your Unique ID " + uniqueId.id.toString());
if (uniqueId.id != null && uniqueId.id != "") { if (uniqueId.id != null && uniqueId.id != "") {
Navigator.of(context).pushReplacement(new MaterialPageRoute( if (!settingModel.isNullId()) {
builder: (BuildContext context) => Map(), Navigator.of(context).pushReplacement(new MaterialPageRoute(
)); builder: (BuildContext context) => Map(),
));
} else {
this._settingBloc.setSetting(
new SettingModel(this._hostController.text, uniqueId.id),
);
}
} }
}); });
} }
@ -78,7 +95,7 @@ class _SettingState extends State<Setting> {
FlatButton( FlatButton(
onPressed: () { onPressed: () {
this._settingBloc.setSetting( this._settingBloc.setSetting(
new SettingModel(this._hostController.text), new SettingModel(this._hostController.text, null),
); );
}, },
child: Text("Save"), child: Text("Save"),

View File

@ -2,8 +2,8 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:geo_app/bloc/setting.dart'; import 'package:geo_app/bloc/setting.dart';
import 'package:geo_app/component/loader.dart'; import 'package:geo_app/component/loader.dart';
import 'package:geo_app/page/setting.dart';
import 'package:geo_app/page/map.dart'; import 'package:geo_app/page/map.dart';
import 'package:geo_app/page/setting.dart';
class Startup extends StatefulWidget { class Startup extends StatefulWidget {
@override @override
@ -22,8 +22,7 @@ class _StartupState extends State<Startup> {
_settingBloc.getSetting(); _settingBloc.getSetting();
_settingBloc.subject.listen((settingModel) { _settingBloc.subject.listen((settingModel) {
if ((settingModel.host == "" || settingModel.host == null) && if (settingModel.isNullHost() && settingModel.isNullId()) {
(settingModel.id == "" || settingModel.id == null)) {
Navigator.of(context).pushReplacement(new MaterialPageRoute( Navigator.of(context).pushReplacement(new MaterialPageRoute(
builder: (BuildContext context) => Setting(), builder: (BuildContext context) => Setting(),
)); ));

View File

@ -23,6 +23,7 @@ class PositionProvider {
); );
return ResponseModel.fromJson(response.data); return ResponseModel.fromJson(response.data);
} on DioError catch (e) { } on DioError catch (e) {
print(e);
return ResponseModel.fromJson(e.response.data); return ResponseModel.fromJson(e.response.data);
} }
} }

View File

@ -1,6 +1,13 @@
# Generated by pub # Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile # See https://dart.dev/tools/pub/glossary#lockfile
packages: packages:
_fe_analyzer_shared:
dependency: transitive
description:
name: _fe_analyzer_shared
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
adhara_socket_io: adhara_socket_io:
dependency: "direct main" dependency: "direct main"
description: description:
@ -14,7 +21,7 @@ packages:
name: analyzer name: analyzer
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.38.5" version: "0.39.2+1"
archive: archive:
dependency: transitive dependency: transitive
description: description:
@ -36,13 +43,6 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.4.0" version: "2.4.0"
background_fetch:
dependency: transitive
description:
name: background_fetch
url: "https://pub.dartlang.org"
source: hosted
version: "0.3.2"
background_location: background_location:
dependency: "direct main" dependency: "direct main"
description: description:
@ -133,19 +133,12 @@ packages:
name: dio name: dio
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.0.7" version: "3.0.8"
flutter: flutter:
dependency: "direct main" dependency: "direct main"
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
flutter_background_geolocation:
dependency: "direct main"
description:
name: flutter_background_geolocation
url: "https://pub.dartlang.org"
source: hosted
version: "1.4.5"
flutter_test: flutter_test:
dependency: "direct dev" dependency: "direct dev"
description: flutter description: flutter
@ -156,13 +149,6 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
front_end:
dependency: transitive
description:
name: front_end
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.27"
glob: glob:
dependency: transitive dependency: transitive
description: description:
@ -190,7 +176,7 @@ packages:
name: http name: http
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.12.0+2" version: "0.12.0+3"
http_parser: http_parser:
dependency: transitive dependency: transitive
description: description:
@ -218,21 +204,14 @@ packages:
name: json_annotation name: json_annotation
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.0.0" version: "3.0.1"
json_serializable: json_serializable:
dependency: "direct main" dependency: "direct main"
description: description:
name: json_serializable name: json_serializable
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.2.3" version: "3.2.5"
kernel:
dependency: transitive
description:
name: kernel
url: "https://pub.dartlang.org"
source: hosted
version: "0.3.27"
logging: logging:
dependency: transitive dependency: transitive
description: description:
@ -370,7 +349,7 @@ packages:
name: source_gen name: source_gen
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.9.4+6" version: "0.9.4+7"
source_span: source_span:
dependency: transitive dependency: transitive
description: description:

View File

@ -23,15 +23,14 @@ dependencies:
# The following adds the Cupertino Icons font to your application. # The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons. # Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^0.1.2 cupertino_icons: ^0.1.2
google_maps_flutter: ^0.5.21+8 google_maps_flutter: ^0.5.21+15
background_location: ^0.0.9+1 background_location: ^0.0.9
adhara_socket_io: ^0.4.1 adhara_socket_io: ^0.4.1
http: ^0.12.0+2 http: ^0.12.0+2
json_serializable: ^3.2.3 json_serializable: ^3.2.3
shared_preferences: ^0.5.4+3 shared_preferences: ^0.5.6
rxdart: ^0.23.1 rxdart: ^0.23.1
dio: ^3.0.7 dio: ^3.0.7
flutter_background_geolocation: ^1.4.5
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
@ -52,6 +51,7 @@ flutter:
# To add assets to your application, add an assets section, like this: # To add assets to your application, add an assets section, like this:
assets: assets:
- assets/images/server.png - assets/images/server.png
- assets/images/logo.png
# An image asset can refer to one or more resolution-specific "variants", see # An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware. # https://flutter.dev/assets-and-images/#resolution-aware.