Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
Sai Srinivas
GEN_ERP_2025
Commits
eff64c98
Commit
eff64c98
authored
Nov 21, 2025
by
Sai Srinivas
Browse files
21-11-2025 tracking location services
parent
d2939607
Changes
10
Show whitespace changes
Inline
Side-by-side
android/app/src/main/AndroidManifest.xml
View file @
eff64c98
...
...
@@ -22,6 +22,7 @@
<uses-permission
android:name=
"android.permission.WRITE_EXTERNAL_STORAGE"
/>
<uses-permission
android:name=
"android.permission.READ_CONTACTS"
/>
<uses-permission
android:name=
"android.permission.WRITE_CONTACTS"
/>
<uses-permission
android:name=
"android.permission.WAKE_LOCK"
/>
<application
android:name=
"${applicationName}"
...
...
@@ -77,6 +78,12 @@
</intent-filter>
</activity>
<service
android:name=
"com.pravera.flutter_foreground_task.service.ForegroundService"
android:foregroundServiceType=
"location"
android:exported=
"false"
/>
<meta-data
android:name=
"flutter_deeplinking_enabled"
android:value=
"true"
/>
...
...
lib/Notifiers/CheckInProvider.dart
View file @
eff64c98
...
...
@@ -14,6 +14,7 @@ import 'package:provider/provider.dart';
import
'../Utils/BackgroundLocationService.dart'
;
import
'../Utils/SharedpreferencesService.dart'
;
import
'../Utils/backgroundServiceNew.dart'
;
import
'../Utils/background_service.dart'
;
import
'../Utils/commonServices.dart'
;
import
'../services/api_calling.dart'
;
...
...
@@ -229,6 +230,8 @@ class CheckInOutProvider with ChangeNotifier {
if
(
data
.
error
==
0
)
{
toast
(
context
,
"CheckedIn Successfully"
);
await
BackgroundLocationService
.
startLocationService
(
context
);
await
BackgroundLocationServiceNew
.
init
();
await
BackgroundLocationServiceNew
.
start
();
locationController
.
clear
();
dispose
();
Navigator
.
pop
(
context
,
true
);
...
...
@@ -266,6 +269,7 @@ class CheckInOutProvider with ChangeNotifier {
if
(
data
.
error
==
0
)
{
toast
(
context
,
"Check-Out Successful"
);
await
BackgroundLocationService
.
stopLocationService
();
await
BackgroundLocationServiceNew
.
stop
();
locationController
.
clear
();
dispose
();
Navigator
.
pop
(
context
,
true
);
...
...
lib/Notifiers/HomeScreenNotifier.dart
View file @
eff64c98
import
'package:flutter/foundation.dart'
;
import
'package:flutter/material.dart'
;
import
'package:generp/Utils/SharedpreferencesService.dart'
;
import
'package:generp/Utils/backgroundServiceNew.dart'
;
import
'package:generp/screens/LoginScreen.dart'
;
import
'package:generp/services/api_calling.dart'
;
import
'package:intl/intl.dart'
;
...
...
@@ -77,6 +78,8 @@ class HomescreenNotifier extends ChangeNotifier {
var
lastLocationTime
=
await
SharedpreferencesService
().
getString
(
"lastLocationTime"
,
);
notifyListeners
();
print
(
"lastLocationTime:
$lastLocationTime
"
);
...
...
@@ -112,6 +115,7 @@ class HomescreenNotifier extends ChangeNotifier {
if
(
_att_status
==
0
)
{
webSocketManager
.
close
();
await
BackgroundLocationService
.
stopLocationService
();
BackgroundLocationServiceNew
.
stop
();
_onlineStatus
=
"Offline"
;
...
...
@@ -151,11 +155,14 @@ class HomescreenNotifier extends ChangeNotifier {
// print("Status knlknn offine");
}
await
BackgroundLocationService
.
startLocationService
(
context
);
await
BackgroundLocationServiceNew
.
init
();
await
BackgroundLocationServiceNew
.
start
();
// print("setstatus:$setstatus");
}
else
if
(
_att_status
==
2
)
{
// print("att_status:$att_status");
webSocketManager
.
close
();
await
BackgroundLocationService
.
stopLocationService
();
await
BackgroundLocationServiceNew
.
stop
();
_onlineStatus
=
"Offline"
;
...
...
lib/Notifiers/LogoutNotifier.dart
View file @
eff64c98
...
...
@@ -5,6 +5,7 @@ import 'package:generp/screens/LoginScreen.dart';
import
'package:generp/services/api_calling.dart'
;
import
'../Utils/BackgroundLocationService.dart'
;
import
'../Utils/backgroundServiceNew.dart'
;
class
LogoutNotifier
extends
ChangeNotifier
{
bool
_logoutButtonClicked
=
false
;
...
...
@@ -33,6 +34,8 @@ class LogoutNotifier extends ChangeNotifier {
_isLoading
=
false
;
_logoutButtonClicked
=
false
;
await
BackgroundLocationService
.
stopLocationService
();
await
BackgroundLocationServiceNew
.
stop
();
SharedpreferencesService
().
clearPreferences
();
Navigator
.
push
(
context
,
...
...
lib/Notifiers/loginNotifier.dart
View file @
eff64c98
...
...
@@ -184,6 +184,12 @@ class Loginnotifier extends ChangeNotifier {
SharedpreferencesService
().
saveString
(
"UserName"
,
data
.
name
!);
SharedpreferencesService
().
saveString
(
"UserEmail"
,
data
.
emailId
!);
SharedpreferencesService
().
saveString
(
"Session_id"
,
data
.
sessionId
!);
SharedpreferencesService
().
saveString
(
"user"
,
data
.
userId
!);
SharedpreferencesService
().
saveString
(
"session"
,
data
.
sessionId
!);
print
(
"USER ID :
${data.userId}
"
);
print
(
"SESSISON ID:
${data.sessionId}
"
);
var
roles
=
data
.
permissions
!.
toString
();
SharedpreferencesService
().
saveString
(
"roles"
,
roles
);
...
...
lib/Utils/backgroundServiceNew.dart
0 → 100644
View file @
eff64c98
// lib/services/background_location_service.dart
import
'dart:async'
;
import
'package:flutter/foundation.dart'
;
import
'package:flutter_foreground_task/flutter_foreground_task.dart'
;
import
'package:geolocator/geolocator.dart'
;
import
'package:provider/provider.dart'
;
import
'../Notifiers/HomeScreenNotifier.dart'
;
import
'../services/api_calling.dart'
;
import
'SharedpreferencesService.dart'
;
@pragma
(
'vm:entry-point'
)
void
startCallback
(
)
{
FlutterForegroundTask
.
setTaskHandler
(
LocationTaskHandler
());
}
class
LocationTaskHandler
extends
TaskHandler
{
StreamSubscription
<
Position
>?
_stream
;
String
?
_empId
;
String
?
_sessionId
;
@override
Future
<
void
>
onStart
(
DateTime
timestamp
,
TaskStarter
starter
)
async
{
// Load user data
_empId
=
await
SharedpreferencesService
().
getString
(
"user"
);
_sessionId
=
await
SharedpreferencesService
().
getString
(
"session"
);
// var prov = Provider.of<HomescreenNotifier>(context, listen: false);
// _empId = prov.empId;
// _sessionId = prov.session;
print
(
"DATA :
${_empId}
"
);
print
(
"DATA :
${_sessionId}
"
);
if
(
_empId
==
null
||
_sessionId
==
null
)
{
FlutterForegroundTask
.
updateService
(
notificationTitle:
"GEN ERP"
,
notificationText:
"Please login first"
,
);
return
;
}
// Start real-time location stream (when moving)
_stream
=
Geolocator
.
getPositionStream
(
locationSettings:
const
LocationSettings
(
accuracy:
LocationAccuracy
.
high
,
distanceFilter:
20
,
// Only send if moved 20 meters
),
).
listen
((
position
)
{
_sendLocationToApi
(
position
);
});
// Send first location immediately
_sendCurrentLocationOnce
();
FlutterForegroundTask
.
updateService
(
notificationTitle:
"GEN ERP"
,
notificationText:
"Live tracking active"
,
);
}
Future
<
void
>
_sendCurrentLocationOnce
()
async
{
try
{
final
position
=
await
Geolocator
.
getCurrentPosition
(
desiredAccuracy:
LocationAccuracy
.
high
,
timeLimit:
const
Duration
(
seconds:
15
),
);
await
_sendLocationToApi
(
position
);
}
catch
(
e
)
{
if
(
kDebugMode
)
print
(
"Initial location failed:
$e
"
);
}
}
Future
<
void
>
_sendLocationToApi
(
Position
position
)
async
{
final
location
=
"
${position.latitude}
,
${position.longitude}
"
;
_empId
=
await
SharedpreferencesService
().
getString
(
"user"
);
_sessionId
=
await
SharedpreferencesService
().
getString
(
"session"
);
print
(
"DATA111 :
${_empId}
"
);
print
(
"DATA111 :
${_sessionId}
"
);
try
{
final
result
=
await
ApiCalling
.
trackLiveLocationEmpolyeeAPI
(
_empId
!,
_sessionId
!,
location
,
);
if
(
result
!=
null
&&
result
.
error
==
"0"
)
{
FlutterForegroundTask
.
updateService
(
notificationTitle:
"GEN ERP"
,
notificationText:
"Location sent •
${DateTime.now().toString().substring(11, 19)}
"
,
);
}
else
{
FlutterForegroundTask
.
updateService
(
notificationText:
"Sync failed • Retrying..."
,
);
}
}
catch
(
e
)
{
FlutterForegroundTask
.
updateService
(
notificationText:
"No network • Retrying..."
,
);
}
// Save last sent time
final
time
=
DateTime
.
now
().
toString
().
substring
(
11
,
19
);
SharedpreferencesService
().
saveString
(
"lastLocationTime"
,
time
);
}
// This runs every 6 minutes (fallback when not moving)
@override
void
onRepeatEvent
(
DateTime
timestamp
)
{
_sendCurrentLocationOnce
();
}
@override
Future
<
void
>
onDestroy
(
DateTime
timestamp
,
bool
isTimeout
)
async
{
_stream
?.
cancel
();
}
}
// Main Service Controller
class
BackgroundLocationServiceNew
{
static
Future
<
void
>
init
()
async
{
FlutterForegroundTask
.
init
(
androidNotificationOptions:
AndroidNotificationOptions
(
channelId:
'gen_erp_location_channel'
,
channelName:
'GEN ERP Tracking'
,
channelDescription:
'Sends location every 6 minutes'
,
channelImportance:
NotificationChannelImportance
.
HIGH
,
priority:
NotificationPriority
.
HIGH
,
showBadge:
true
,
visibility:
NotificationVisibility
.
VISIBILITY_SECRET
),
iosNotificationOptions:
const
IOSNotificationOptions
(),
foregroundTaskOptions:
ForegroundTaskOptions
(
eventAction:
ForegroundTaskEventAction
.
repeat
(
360000
),
// Every 6 minutes
autoRunOnBoot:
false
,
// Prevents crash on boot
allowWakeLock:
true
,
allowWifiLock:
true
,
),
);
}
static
Future
<
bool
>
get
isRunning
=>
FlutterForegroundTask
.
isRunningService
;
static
Future
<
void
>
start
()
async
{
if
(
await
isRunning
)
{
await
FlutterForegroundTask
.
restartService
();
}
else
{
await
FlutterForegroundTask
.
startService
(
notificationTitle:
'GEN ERP'
,
notificationText:
'Starting location tracking...'
,
callback:
startCallback
,
);
}
}
static
Future
<
void
>
stop
()
async
{
await
FlutterForegroundTask
.
stopService
();
}
}
\ No newline at end of file
lib/services/api_calling.dart
View file @
eff64c98
...
...
@@ -5821,4 +5821,29 @@ class ApiCalling {
// return null;
// }
// }
static
Future
<
CommonResponse
?>
trackLiveLocationEmpolyeeAPI
(
empId
,
session
,
location
)
async
{
try
{
Map
<
String
,
String
>
data
=
{
'emp_id'
:
(
empId
).
toString
(),
'session_id'
:
(
session
).
toString
(),
'location'
:
(
location
),
};
// print(data);
final
res
=
await
post
(
data
,
liveLocationStatusUrl
,
{});
if
(
res
!=
null
)
{
print
(
"BACKGROUND LOCATION DATA :
${data}
"
);
debugPrint
(
"BACKGROUND LOCATION:
${res.body}
"
);
// print("check_session: ${res.body}");
return
CommonResponse
.
fromJson
(
jsonDecode
(
res
.
body
));
}
else
{
debugPrint
(
"Null Response"
);
return
null
;
}
}
catch
(
e
)
{
debugPrint
(
'hello bev=bug
$e
'
);
return
null
;
}
}
}
lib/services/api_names.dart
View file @
eff64c98
const
baseUrl
=
"https://erp.gengroup.in/ci/app/"
;
const
baseUrl_test
=
"https://erp.gengroup.in/ci/app/Api_home/"
;
const
trackingUrl
=
"https://erp.gengroup.in/ci/app/Home/"
;
// var WEB_SOCKET_URL = "wss://ws.erp.gengroup.in/?type=user&route=employe_live_location_update&session_id=${Sessionid}";
const
getAppVersionUrl
=
"https://erp.gengroup.in/ci/assets/appversion.json"
;
...
...
@@ -212,3 +213,4 @@ const AdvanceListUrl ="${baseUrl_test}advance_list";
const
createRazorpayUpiQrUrl
=
"
${baseUrl_test}
create_razorpay_upi_qr"
;
const
fetchRazorpayUpiQrStatusUrl
=
"
${baseUrl_test}
fetch_razorpay_upi_qr_status"
;
const
liveLocationStatusUrl
=
"
${trackingUrl}
sattendance_live_location_update"
;
\ No newline at end of file
pubspec.lock
View file @
eff64c98
...
...
@@ -598,6 +598,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.12.0"
flutter_foreground_task:
dependency: "direct main"
description:
name: flutter_foreground_task
sha256: "9f1b25a81db95d7119d2c5cffc654048cbdd49d4056183e1beadc1a6a38f3e29"
url: "https://pub.dev"
source: hosted
version: "9.1.0"
flutter_html:
dependency: "direct main"
description:
...
...
pubspec.yaml
View file @
eff64c98
...
...
@@ -95,6 +95,7 @@ dependencies:
photo_view
:
^0.14.0
flutter_contacts
:
^1.1.9+2
open_filex
:
^4.7.0
flutter_foreground_task
:
^9.1.0
dev_dependencies
:
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment