geofence_updated_code

This commit is contained in:
2026-03-28 18:10:00 +05:30
parent da5d6cc1b3
commit 76e4fca075
622 changed files with 72142 additions and 569 deletions
+2 -2
View File
@@ -11,8 +11,8 @@ android {
applicationId "com.cpm.lorealbaautomation"
//noinspection OldTargetApi
targetSdk 34
versionCode 24
versionName "3.2"
versionCode 23
versionName "3.1"
multiDexEnabled true
useLibrary 'org.apache.http.legacy'
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+2 -2
View File
@@ -11,8 +11,8 @@
"type": "SINGLE",
"filters": [],
"attributes": [],
"versionCode": 24,
"versionName": "3.2",
"versionCode": 23,
"versionName": "3.1",
"outputFile": "app-release.apk"
}
],
@@ -0,0 +1,122 @@
package com.cpm.lorealbaautomation;
import static com.google.android.gms.location.Priority.PRIORITY_HIGH_ACCURACY;
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationRequest;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationCallback;
import com.google.android.gms.location.LocationResult;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.location.Priority;
public class LocationEngine {
public interface LocationResultListener {
void onLocationReady(Location location, float accuracy);
void onFailure(String msg);
}
private final Context context;
private final FusedLocationProviderClient fusedClient;
private LocationCallback locationCallback;
private Location bestLocation = null;
private float bestAccuracy = Float.MAX_VALUE;
private Handler handler = new Handler(Looper.getMainLooper());
public LocationEngine(Context context) {
this.context = context;
fusedClient = LocationServices.getFusedLocationProviderClient(context);
}
public void start(LocationResultListener listener) {
com.google.android.gms.location.LocationRequest request = new com.google.android.gms.location.LocationRequest.Builder(Priority.PRIORITY_HIGH_ACCURACY, 2000L)
.setMinUpdateIntervalMillis(1000L)
.setMaxUpdateDelayMillis(3000L)
.setWaitForAccurateLocation(true) // Optional, improves first fix
.build();
/* LocationRequest request = new LocationRequest.Builder(Priority.PRIORITY_HIGH_ACCURACY, 2000L) // 👈 IMPORTANT
.setMinUpdateIntervalMillis(1000L)
.setMaxUpdateDelayMillis(3000L)
.setWaitForAccurateLocation(true)
.build();*/
locationCallback = new LocationCallback() {
@Override
public void onLocationResult(@NonNull LocationResult result) {
for (Location location : result.getLocations()) {
if (location == null) continue;
float accuracy = location.getAccuracy();
// 🔥 Track best location always
if (accuracy < bestAccuracy) {
bestAccuracy = accuracy;
bestLocation = location;
}
Log.d("LocationEngine",
"Lat: " + location.getLatitude()
+ " Lng: " + location.getLongitude()
+ " Acc: " + accuracy);
// ✅ Accept good or stable location
if (accuracy <= 80) {
stop();
listener.onLocationReady(location, accuracy);
return;
}
}
}
};
if (ActivityCompat.checkSelfPermission(context,
Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
listener.onFailure("Permission not granted");
return;
}
fusedClient.requestLocationUpdates(request, locationCallback, Looper.getMainLooper());
// ⏱ Timeout fallback (VERY IMPORTANT)
handler.postDelayed(() -> {
if (bestLocation != null) {
Log.d("LocationEngine", "Using fallback location");
listener.onLocationReady(bestLocation, bestAccuracy);
} else {
listener.onFailure("Unable to fetch location");
}
stop();
}, 8000);
}
public void stop() {
if (locationCallback != null) {
fusedClient.removeLocationUpdates(locationCallback);
}
handler.removeCallbacksAndMessages(null);
}
}
@@ -2,7 +2,6 @@ package com.cpm.lorealbaautomation.dailyactivity;
import static com.cpm.lorealbaautomation.constant.CommonFunctions.checkNetIsAvailable;
import static com.cpm.lorealbaautomation.constant.CommonFunctions.getCurrentTime;
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
@@ -11,15 +10,12 @@ import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentSender;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Environment;
import android.os.Looper;
import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
@@ -27,7 +23,6 @@ import androidx.core.content.ContextCompat;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import android.os.Looper;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MenuItem;
@@ -35,21 +30,16 @@ import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.Toast;
import com.cpm.lorealbaautomation.Database.Lorealba_Database;
import com.google.android.gms.common.api.ResolvableApiException;
import com.cpm.lorealbaautomation.LocationEngine;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationCallback;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationResult;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.location.LocationSettingsRequest;
import com.google.android.gms.location.Priority;
import com.google.android.gms.location.SettingsClient;
import com.google.gson.Gson;
import com.cpm.lorealbaautomation.BuildConfig;
import com.cpm.lorealbaautomation.Database.Lorealba_Database;
import com.cpm.lorealbaautomation.DealarBoardActivity;
import com.cpm.lorealbaautomation.R;
import com.cpm.lorealbaautomation.constant.AlertandMessages;
@@ -104,6 +94,7 @@ public class StoreImageActivity extends AppCompatActivity implements View.OnClic
private ImageView img_cam, img_clicked;
private String _pathforcheck, _path, str, img_str, selfie_imge, visit_date, username, counter_id, userType;
private Lorealba_Database db;
private LocationEngine locationEngine;
private Runnable run;
private boolean isGeoTagAlertShown = false;
private Toolbar toolbar;
@@ -117,11 +108,14 @@ public class StoreImageActivity extends AppCompatActivity implements View.OnClic
private FusedLocationProviderClient fusedLocationClient = null;
private LocationCallback locationCallback = null;
private SharedPreferences.Editor editor = null;
private boolean isLocationFetching = false;
private ProgressBar locationLoader;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_store_image);
locationEngine = new LocationEngine(this);
db = new Lorealba_Database(this);
db.open();
SharedPreferences preferences = PrefHelper.getPrefs(this);
@@ -130,6 +124,13 @@ public class StoreImageActivity extends AppCompatActivity implements View.OnClic
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
img_cam = (ImageView) findViewById(R.id.img_selfie);
img_clicked = (ImageView) findViewById(R.id.img_cam_selfie);
locationLoader = findViewById(R.id.locationLoader);
locationLoader.setVisibility(View.VISIBLE);
getWindow().setFlags(
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
);
btn_save = (Button) findViewById(R.id.btn_save_selfie);
toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
@@ -169,9 +170,8 @@ public class StoreImageActivity extends AppCompatActivity implements View.OnClic
} catch (Exception e) {
e.fillInStackTrace();
}
checkAndRequestPermissions();
getLastLocation();
fetchLocationAndCheckGeoFence();
}
private void checkdates() {
@@ -546,7 +546,7 @@ public class StoreImageActivity extends AppCompatActivity implements View.OnClic
}
} else {
/// checking GeoFencing
getLastLocation();
fetchLocationAndCheckGeoFence();
}
}
@@ -557,13 +557,13 @@ public class StoreImageActivity extends AppCompatActivity implements View.OnClic
success_geoTag = true;
}
if (!success_geoTag) {
getLastLocation();
fetchLocationAndCheckGeoFence();
}
checkgpsEnableDevice();
// checkgpsEnableDevice();
getMid();
}
private void checkgpsEnableDevice() {
/*private void checkgpsEnableDevice() {
if (!hasGPSDevice(this)) {
Toast.makeText(this, "Gps not Supported", Toast.LENGTH_SHORT).show();
}
@@ -617,11 +617,13 @@ public class StoreImageActivity extends AppCompatActivity implements View.OnClic
for (Location location : locationResult.getLocations()) {
if (location != null) {
if(location.getAccuracy()<80){
lat = location.getLatitude();
lon = location.getLongitude();
}
}
}
}
};
// Don't forget permissions check
@@ -640,7 +642,7 @@ public class StoreImageActivity extends AppCompatActivity implements View.OnClic
final List<String> providers = mgr.getAllProviders();
if (providers == null) return false;
return providers.contains(LocationManager.GPS_PROVIDER);
}
}*/
private void DownloadJCP(final Context context, final ProgressDialog loading) {
try {
@@ -676,7 +678,7 @@ public class StoreImageActivity extends AppCompatActivity implements View.OnClic
if (jcpObject != null && db.insertJCPData(jcpObject)) {
Log.d("jcpdatanew","jcp data inserted");
/// checking GeoFencing
getLastLocation();
fetchLocationAndCheckGeoFence();
AlertandMessages.showToastMsg(context, "Journey Plan Download Successfully.");
JourneyPlan jcp = db.getBIDfromJCP(username, counter_id);
if (jcp != null && jcp.getCheckout() != null && !jcp.getCheckout().isEmpty() && jcp.getCheckout().equals("Y")) {
@@ -832,7 +834,7 @@ public class StoreImageActivity extends AppCompatActivity implements View.OnClic
boolean allPermissionsGranted = Integer.valueOf(PackageManager.PERMISSION_GRANTED).equals(perms.get(Manifest.permission.CAMERA)) && Integer.valueOf(PackageManager.PERMISSION_GRANTED).equals(perms.get(Manifest.permission.ACCESS_NETWORK_STATE)) && Integer.valueOf(PackageManager.PERMISSION_GRANTED).equals(perms.get(Manifest.permission.ACCESS_COARSE_LOCATION)) && Integer.valueOf(PackageManager.PERMISSION_GRANTED).equals(perms.get(Manifest.permission.ACCESS_FINE_LOCATION)) && Integer.valueOf(PackageManager.PERMISSION_GRANTED).equals(perms.get(Manifest.permission.READ_PHONE_STATE));
if (allPermissionsGranted) {
getLastLocation();
fetchLocationAndCheckGeoFence();
} else {
//test("", "Some permissions are not granted ask again ");
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA) || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_NETWORK_STATE) || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_COARSE_LOCATION) || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION) || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_PHONE_STATE)) {
@@ -858,7 +860,46 @@ public class StoreImageActivity extends AppCompatActivity implements View.OnClic
}
}
private void getLastLocation() {
private void fetchLocationAndCheckGeoFence() {
if (isLocationFetching) return; // prevent multiple calls
isLocationFetching = true;
locationLoader.setVisibility(View.VISIBLE);
getWindow().setFlags(
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
);
locationEngine.start(new LocationEngine.LocationResultListener() {
@Override
public void onLocationReady(Location location, float accuracy) {
isLocationFetching = false;
locationLoader.setVisibility(View.GONE);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
lat = location.getLatitude();
lon = location.getLongitude();
Log.d("GeoFence", "Lat: " + lat + ", Lon: " + lon + ", Acc: " + accuracy);
// 🔥 Pass accuracy also
checkingGeoFencing(getMid(), accuracy);
}
@Override
public void onFailure(String msg) {
isLocationFetching = false;
locationLoader.setVisibility(View.GONE);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
Toast.makeText(StoreImageActivity.this, msg, Toast.LENGTH_SHORT).show();
}
});
}
/*private void fetchLocationAndCheckGeoFence() {
if (fusedLocationClient == null) {
fusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
}
@@ -869,7 +910,7 @@ public class StoreImageActivity extends AppCompatActivity implements View.OnClic
return;
}
// First, try to get the last known location
fusedLocationClient.getLastLocation()
fusedLocationClient.fetchLocationAndCheckGeoFence()
.addOnSuccessListener(location -> {
if (location != null) {
lat = location.getLatitude();
@@ -884,38 +925,74 @@ public class StoreImageActivity extends AppCompatActivity implements View.OnClic
// Fallback: explicit request for a new location
requestNewLocation();
});
}
}*/
private void requestNewLocation() {
LocationRequest locationRequest = new LocationRequest.Builder(Priority.PRIORITY_HIGH_ACCURACY, 5000)
.setMinUpdateIntervalMillis(3000)
.setMaxUpdateDelayMillis(6000)
/*private void requestNewLocation() {
LocationRequest locationRequest = new LocationRequest.Builder(
Priority.PRIORITY_HIGH_ACCURACY, 2000)
.setMinUpdateIntervalMillis(1000)
.setMaxUpdateDelayMillis(3000)
.setMinUpdateDistanceMeters(0f)
.setWaitForAccurateLocation(true)
.build();
locationCallback = new LocationCallback() {
@Override
public void onLocationResult(@NonNull LocationResult locationResult) {
for (Location location : locationResult.getLocations()) {
if (location != null) {
float accuracy = location.getAccuracy();
Log.d("Location", "Lat: " + location.getLatitude()
+ ", Lng: " + location.getLongitude()
+ ", Accuracy: " + accuracy);
// 🎯 IMPORTANT: Accept only accurate location
if (accuracy <= 80) {
lat = location.getLatitude();
lon = location.getLongitude();
Log.d("Location", "Lat: " + lat + ", Lng: " + lon + " (new)");
checkingGeoFencing(getMid());
stopLocationUpdates(); // Stop updates after first valid location
Log.d("Location", "Accurate location received ✅");
checkingGeoFencing(getMid(),accuracy);
stopLocationUpdates(); // stop after good fix
break;
} else {
Log.d("Location", "Waiting for better accuracy...");
}
}
}
}
};
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// Request permissions if not granted
!= PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
checkAndRequestPermissions();
return;
}
fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper());
}
fusedLocationClient.requestLocationUpdates(
locationRequest,
locationCallback,
Looper.getMainLooper()
);
// ⏱ OPTIONAL: timeout (avoid infinite wait)
new android.os.Handler().postDelayed(() -> {
Log.d("Location", "Timeout reached ⏳");
stopLocationUpdates();
}, 10000); // 10 seconds max
}*/
private void stopLocationUpdates() {
if (fusedLocationClient != null && locationCallback != null) {
@@ -938,16 +1015,23 @@ public class StoreImageActivity extends AppCompatActivity implements View.OnClic
stopLocationUpdates();
}
private void checkingGeoFencing(JourneyPlan jcp) {
private void checkingGeoFencing(JourneyPlan jcp, float accuracy) {
if (jcp != null && jcp.getBID() != null) {
if (jcp.getGeoTag() != null && !jcp.getGeoTag().equalsIgnoreCase(CommonString.KEY_N) && jcp.getGeoFencingAllow() != null && jcp.getGeoFencingAllow() == 1) {
int distance = jcp.getGeoFencingRadius() != null ? jcp.getGeoFencingRadius() : 0;
int current_dist_from_store_using_lat = 0;
Log.d("latdata", lat + "," + lon + "," + jcp.getLatitude() + "," + jcp.getLongitude());
if (jcp.getLatitude() != 0.0 && jcp.getLongitude() != 0.0 && jcp.getGeoFencingRadius() != 0 && lat != 0.0 && lon != 0.0) {
current_dist_from_store_using_lat = DistanceUtils.calculateDistanceInMeters(lat, lon, jcp.getLatitude(), jcp.getLongitude());
int adjustedDistance = current_dist_from_store_using_lat - (int) accuracy;
Log.d("GeoFence", "Actual: " + current_dist_from_store_using_lat +
" Accuracy: " + accuracy +
" Adjusted: " + adjustedDistance);
Log.d("TagLoc", "Radius " + distance + "\nCurrent dist " + current_dist_from_store_using_lat);
if (current_dist_from_store_using_lat > distance) {
// if (current_dist_from_store_using_lat > distance) {
if (adjustedDistance > distance) {
String msg = getString(R.string.you_need_to_be_within) + " " + distance + " metres " + getString(R.string.you_need_to_be_in_the_store) +
"\n\n" + getString(R.string.distance_from_the_store) + " " + current_dist_from_store_using_lat + " " + getString(R.string.meters);
if (isFinishing() || isDestroyed()) {
@@ -990,5 +1074,6 @@ public class StoreImageActivity extends AppCompatActivity implements View.OnClic
}
}
}
@@ -31,6 +31,7 @@ import androidx.appcompat.widget.Toolbar;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import com.cpm.lorealbaautomation.LocationEngine;
import com.google.android.gms.common.api.ResolvableApiException;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationCallback;
@@ -106,25 +107,84 @@ public class GeoTaggingActivity extends AppCompatActivity implements OnMapReadyC
fusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
geocoder = new Geocoder(this);
declaration();
fab.setOnClickListener(view -> {
/*fab.setOnClickListener(view -> {
try {
startLocationUpdates();
if (!img_str.isEmpty()) {
if (db.InsertSTOREgeotag(jcpGetset.getStoreId().toString(), counter_id, jcpGetset.getBID().toString(), username, latitude, longitude, img_str) > 0) {
if (checkNetIsAvailable(view.getContext())) {
new GeoTagUpload().execute();
} else {
AlertandMessages.showToastMsg(context, getResources().getString(R.string.nonetwork));
}
} else {
AlertandMessages.showToastMsg(context, "Error in saving Geotag");
}
startLocationUpdates(true);
} else {
AlertandMessages.showToastMsg(view.getContext(), getResources().getString(R.string.takeimage));
}
} catch (Exception e) {
e.fillInStackTrace();
}
});*/
fab.setOnClickListener(view -> {
try {
if (!img_str.isEmpty()) {
LocationEngine engine = new LocationEngine(this);
engine.start(new LocationEngine.LocationResultListener() {
@Override
public void onLocationReady(Location location, float accuracy) {
// ✅ Validate location
if (location == null) {
AlertandMessages.showToastMsg(context, "Unable to fetch location,Please try later");
return;
}
// ✅ Accuracy check (important for geofencing)
if (accuracy > 80) {
AlertandMessages.showToastMsg(context, "Fetching accurate location, please wait...");
return;
}
latitude = location.getLatitude();
longitude = location.getLongitude();
// ✅ Lat/Lng validation
if (latitude == 0.0 || longitude == 0.0) {
AlertandMessages.showToastMsg(context, "Invalid location, please try again");
return;
}
Log.d("GeoTag", "Acc: " + accuracy +","+ latitude + ","+longitude);
updateMapWithLocation(latitude, longitude);
// 🔥 Save geotag
if (db.InsertSTOREgeotag(
jcpGetset.getStoreId().toString(),
counter_id,
jcpGetset.getBID().toString(),
username,
latitude,
longitude,
img_str) > 0) {
if (checkNetIsAvailable(context)) {
new GeoTagUpload().execute();
} else {
AlertandMessages.showToastMsg(context, getString(R.string.nonetwork));
}
} else {
AlertandMessages.showToastMsg(context, "Error in saving Geotag");
}
}
@Override
public void onFailure(String msg) {
Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
}
});
} else {
AlertandMessages.showToastMsg(view.getContext(), getString(R.string.takeimage));
}
} catch (Exception e) {
e.printStackTrace();
}
});
camera_fab.setOnClickListener(view -> {
try {
@@ -173,25 +233,61 @@ public class GeoTaggingActivity extends AppCompatActivity implements OnMapReadyC
}
};
}
private void startLocationUpdates() {
LocationRequest locationRequest = new LocationRequest.Builder(Priority.PRIORITY_HIGH_ACCURACY, 5000)
.setMinUpdateIntervalMillis(3000)
private void startLocationUpdates(boolean save) {
LocationRequest locationRequest = new LocationRequest.Builder(
Priority.PRIORITY_HIGH_ACCURACY, 2000)
.setMinUpdateIntervalMillis(1000)
.setMaxUpdateDelayMillis(3000)
.setWaitForAccurateLocation(true)
.setMaxUpdateDelayMillis(6000)
.build();
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED ||
ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper());
fusedLocationClient.getLastLocation().addOnSuccessListener(this, location -> {
if (location != null && (latitude == 0.0 && longitude == 0.0)) {
fusedLocationClient.requestLocationUpdates(
locationRequest,
new LocationCallback() {
@Override
public void onLocationResult(@NonNull LocationResult locationResult) {
for (Location location : locationResult.getLocations()) {
if (location != null) {
float accuracy = location.getAccuracy();
Log.d("Location", "Accuracy: " + accuracy);
// ✅ Only accept good accuracy
latitude = location.getLatitude();
longitude = location.getLongitude();
Log.d("Location", "Accuracy: " + accuracy +","+ latitude +","+ longitude);
previousLatitude = latitude;
previousLongitude = longitude;
updateMapWithLocation(latitude, longitude);
if (save){
runOnUiThread(() -> {
if (db.InsertSTOREgeotag(jcpGetset.getStoreId().toString(), counter_id, jcpGetset.getBID().toString(), username, latitude, longitude, img_str) > 0) {
if (checkNetIsAvailable(context)) {
new GeoTagUpload().execute();
} else {
AlertandMessages.showToastMsg(context, getResources().getString(R.string.nonetwork));
}
} else {
AlertandMessages.showToastMsg(context, "Error in saving Geotag");
}
});
}
updateMapWithLocation(latitude, longitude);
stopLocationUpdates(); // stop after good fix
break;
}
}
}
},
Looper.getMainLooper()
);
} else {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION},
@@ -199,6 +295,19 @@ public class GeoTaggingActivity extends AppCompatActivity implements OnMapReadyC
}
}
private void stopLocationUpdates() {
if (fusedLocationClient != null && locationCallback != null) {
fusedLocationClient.removeLocationUpdates(locationCallback);
}
}
@Override
protected void onPause() {
super.onPause();
stopLocationUpdates();
}
private void updateMapWithLocation(double lat, double lon) {
if (geocoder != null && mMap != null) {
Log.e("jeevanp", "" + lat);
@@ -242,29 +351,69 @@ public class GeoTaggingActivity extends AppCompatActivity implements OnMapReadyC
@Override
public void onMapReady(@NonNull GoogleMap googleMap) {
mMap = googleMap;
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
mMap.getUiSettings().setZoomControlsEnabled(true);
mMap.getUiSettings().setCompassEnabled(true);
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(latitude, longitude), 15));
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED ||
ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
// ❌ REMOVE this (causes 0,0 jump)
// mMap.moveCamera(...)
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED ||
ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
mMap.setMyLocationEnabled(true);
mMap.getUiSettings().setMyLocationButtonEnabled(true);
startLocationUpdates();
// ✅ Use LocationEngine instead
fetchMapLocation();
} else {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION},
new String[]{
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION
},
LOCATION_PERMISSION_REQUEST_CODE);
}
fusedLocationClient.getLastLocation().addOnSuccessListener(location -> {
if (location != null && (latitude == 0.0 && longitude == 0.0)) {
}
private void fetchMapLocation() {
LocationEngine engine = new LocationEngine(this);
engine.start(new LocationEngine.LocationResultListener() {
@Override
public void onLocationReady(Location location, float accuracy) {
if (location == null) return;
// 🎯 Optional: accuracy check
if (accuracy > 80) {
Log.d("Map", "Waiting for better accuracy...");
return;
}
latitude = location.getLatitude();
longitude = location.getLongitude();
previousLatitude = latitude;
previousLongitude = longitude;
Log.d("Map", "Lat: " + latitude + ", Lng: " + longitude + ", Acc: " + accuracy);
updateMapWithLocation(latitude, longitude);
}
@Override
public void onFailure(String msg) {
Toast.makeText(GeoTaggingActivity.this, msg, Toast.LENGTH_SHORT).show();
}
});
}
@@ -287,7 +436,7 @@ public class GeoTaggingActivity extends AppCompatActivity implements OnMapReadyC
mMap.getUiSettings().setMyLocationButtonEnabled(true);
}
}
startLocationUpdates();
startLocationUpdates(false);
} else {
Toast.makeText(this, "Location permissions are required for geotagging", Toast.LENGTH_LONG).show();
}
@@ -297,13 +446,13 @@ public class GeoTaggingActivity extends AppCompatActivity implements OnMapReadyC
@Override
protected void onResume() {
super.onResume();
checkgpsEnableDevice();
// checkgpsEnableDevice();
}
@Override
protected void onStart() {
super.onStart();
startLocationUpdates();
startLocationUpdates(false);
}
@@ -25,6 +25,13 @@
android:gravity="center"
android:orientation="vertical">
<ProgressBar
android:id="@+id/locationLoader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone"/>
<ImageView
android:id="@+id/img_selfie"
android:layout_width="match_parent"
@@ -25,6 +25,13 @@
android:layout_margin="@dimen/margin_30dp"
android:orientation="vertical">
<ProgressBar
android:id="@+id/locationLoader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone"/>
<ImageView
android:id="@+id/img_selfie"
android:layout_width="match_parent"
@@ -0,0 +1 @@
i/classes_global-synthetics
@@ -0,0 +1 @@
o/classes
@@ -0,0 +1 @@
i/classes_dex
@@ -0,0 +1 @@
o/debug
@@ -0,0 +1 @@
i/classes_global-synthetics
@@ -0,0 +1 @@
o/classes
@@ -0,0 +1 @@
i/debug_dex
@@ -0,0 +1 @@
o/classes
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.androidbuts.multispinnerfilter" >
<uses-sdk android:minSdkVersion="23" />
<application android:allowBackup="true" >
</application>
</manifest>
@@ -0,0 +1,18 @@
{
"version": 3,
"artifactType": {
"type": "AAPT_FRIENDLY_MERGED_MANIFESTS",
"kind": "Directory"
},
"applicationId": "com.androidbuts.multispinnerfilter",
"variantName": "debug",
"elements": [
{
"type": "SINGLE",
"filters": [],
"attributes": [],
"outputFile": "AndroidManifest.xml"
}
],
"elementType": "File"
}
@@ -0,0 +1,6 @@
aarFormatVersion=1.0
aarMetadataVersion=1.0
minCompileSdk=1
minCompileSdkExtension=0
minAndroidGradlePluginVersion=1.0.0
coreLibraryDesugaringEnabled=false
@@ -0,0 +1,2 @@
#- File Locator -
listingFile=../../../outputs/apk/androidTest/debug/output-metadata.json
@@ -0,0 +1,45 @@
int attr hintText 0x0
int color ColorPrimary 0x0
int color ColorPrimaryDark 0x0
int color android_text_color 0x0
int color app_topbar_color 0x0
int color background_color 0x0
int color black 0x0
int color blue 0x0
int color cyan 0x0
int color gray 0x0
int color lightBlue 0x0
int color list_background 0x0
int color list_even 0x0
int color list_header 0x0
int color list_odd 0x0
int color list_selected 0x0
int color primary 0x0
int color primary_dark 0x0
int color primary_pressed 0x0
int color red 0x0
int color ripple 0x0
int color text_color 0x0
int color white 0x0
int dimen activity_horizontal_margin 0x0
int dimen activity_vertical_margin 0x0
int id alertCheckbox 0x0
int id alertSearchEditText 0x0
int id alertSearchListView 0x0
int id alertTextView 0x0
int id empty 0x0
int id listTextViewSpinner 0x0
int id searchMultiSpinner 0x0
int id simpleMultiSpinner 0x0
int layout activity_main 0x0
int layout alert_dialog_listview_search 0x0
int layout item_listview_multiple 0x0
int layout item_listview_single 0x0
int layout textview_for_spinner 0x0
int string type_to_search 0x0
int style DialogWindowTitle 0x0
int style MaterialSpinner 0x0
int style myDialog 0x0
int style myDialogTitle 0x0
int[] styleable MultiSpinnerSearch { 0x0 }
int styleable MultiSpinnerSearch_hintText 0
@@ -0,0 +1,6 @@
#Wed Mar 18 16:02:23 IST 2026
com.androidbuts.multispinnerfilter.library-main-6\:/layout/activity_main.xml=E\:\\LorealBa-Latest-2024\\LorealBa-Latest-2024\\library\\build\\intermediates\\packaged_res\\debug\\layout\\activity_main.xml
com.androidbuts.multispinnerfilter.library-main-6\:/layout/alert_dialog_listview_search.xml=E\:\\LorealBa-Latest-2024\\LorealBa-Latest-2024\\library\\build\\intermediates\\packaged_res\\debug\\layout\\alert_dialog_listview_search.xml
com.androidbuts.multispinnerfilter.library-main-6\:/layout/item_listview_multiple.xml=E\:\\LorealBa-Latest-2024\\LorealBa-Latest-2024\\library\\build\\intermediates\\packaged_res\\debug\\layout\\item_listview_multiple.xml
com.androidbuts.multispinnerfilter.library-main-6\:/layout/item_listview_single.xml=E\:\\LorealBa-Latest-2024\\LorealBa-Latest-2024\\library\\build\\intermediates\\packaged_res\\debug\\layout\\item_listview_single.xml
com.androidbuts.multispinnerfilter.library-main-6\:/layout/textview_for_spinner.xml=E\:\\LorealBa-Latest-2024\\LorealBa-Latest-2024\\library\\build\\intermediates\\packaged_res\\debug\\layout\\textview_for_spinner.xml
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="DialogWindowTitle">
<item name="android:maxLines">1</item>
<item name="android:scrollHorizontally">true</item>
<item name="android:textAppearance">@android:style/TextAppearance.DialogWindowTitle</item>
</style>
<style name="MaterialSpinner" parent="Material.Widget.Spinner">
<item name="rd_style">@style/Material.Drawable.Ripple.Wave.Light</item>
<item name="spn_labelEnable">true</item>
<item name="spn_labelTextSize">18sp</item>
<item name="spn_arrowSwitchMode">true</item>
<item name="spn_arrowAnimDuration">@android:integer/config_shortAnimTime</item>
<item name="spn_arrowInterpolator">@android:anim/decelerate_interpolator</item>
</style>
<style name="myDialog" parent="@android:style/Theme.Holo.Light.Dialog">
<item name="android:windowTitleStyle">@style/myDialogTitle</item>
</style>
<style name="myDialogTitle" parent="@android:style/TextAppearance.DialogWindowTitle">
<item name="android:gravity">center_horizontal</item>
</style>
<declare-styleable name="MultiSpinnerSearch">
<attr format="string" name="hintText"/>
</declare-styleable>
</resources>
@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ColorPrimary">#29CA97</color>
<color name="ColorPrimaryDark">#06ACE4</color>
<color name="android_text_color">#747474</color>
<color name="app_topbar_color">#AAAAAA</color>
<color name="background_color">#E1E2E2</color>
<color name="black">#000000</color>
<color name="blue">#1589FF</color>
<color name="cyan">#00FFFF</color>
<color name="gray">#D1D0CE</color>
<color name="lightBlue">#ADD8E6</color>
<color name="list_background">#06ACE4</color>
<color name="list_even">#AAAAAA</color>
<color name="list_header">#99979C</color>
<color name="list_odd">#E1E2E2</color>
<color name="list_selected">#455FB6</color>
<color name="primary">#3f51b5</color>
<color name="primary_dark">#303f9f</color>
<color name="primary_pressed">#E1E2E2</color>
<color name="red">#FF0000</color>
<color name="ripple">#F06292</color>
<color name="text_color">#686868</color>
<color name="white">#FFFFFF</color>
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
<string name="type_to_search">Type to Search</string>
<style name="DialogWindowTitle">
<item name="android:maxLines">1</item>
<item name="android:scrollHorizontally">true</item>
<item name="android:textAppearance">@android:style/TextAppearance.DialogWindowTitle</item>
</style>
<style name="MaterialSpinner" parent="Widget.AppCompat.Spinner">
<item name="rd_style">@style/Material.Drawable.Ripple.Wave.Light</item>
<item name="spn_labelEnable">true</item>
<item name="spn_labelTextSize">18sp</item>
<item name="spn_arrowSwitchMode">true</item>
<item name="spn_arrowAnimDuration">@android:integer/config_shortAnimTime</item>
<item name="spn_arrowInterpolator">@android:anim/decelerate_interpolator</item>
</style>
<style name="myDialog" parent="@android:style/Theme.Holo.Light.Dialog">
<item name="android:windowTitleStyle">@style/myDialogTitle</item>
</style>
<style name="myDialogTitle" parent="@android:style/TextAppearance.DialogWindowTitle">
<item name="android:gravity">center_horizontal</item>
</style>
</resources>
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<merger version="3"><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="main$Generated" generated="true" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="E:\LorealBa-Latest-2024\LorealBa-Latest-2024\library\src\main\res"/></dataSet><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="main" generated-set="main$Generated" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="E:\LorealBa-Latest-2024\LorealBa-Latest-2024\library\src\main\res"><file name="activity_main" path="E:\LorealBa-Latest-2024\LorealBa-Latest-2024\library\src\main\res\layout\activity_main.xml" qualifiers="" type="layout"/><file name="alert_dialog_listview_search" path="E:\LorealBa-Latest-2024\LorealBa-Latest-2024\library\src\main\res\layout\alert_dialog_listview_search.xml" qualifiers="" type="layout"/><file name="item_listview_multiple" path="E:\LorealBa-Latest-2024\LorealBa-Latest-2024\library\src\main\res\layout\item_listview_multiple.xml" qualifiers="" type="layout"/><file name="item_listview_single" path="E:\LorealBa-Latest-2024\LorealBa-Latest-2024\library\src\main\res\layout\item_listview_single.xml" qualifiers="" type="layout"/><file name="textview_for_spinner" path="E:\LorealBa-Latest-2024\LorealBa-Latest-2024\library\src\main\res\layout\textview_for_spinner.xml" qualifiers="" type="layout"/><file path="E:\LorealBa-Latest-2024\LorealBa-Latest-2024\library\src\main\res\values\colors.xml" qualifiers=""><color name="ColorPrimary">#29CA97</color><color name="ColorPrimaryDark">#06ACE4</color><color name="list_background">#06ACE4</color><color name="blue">#1589FF</color><color name="white">#FFFFFF</color><color name="black">#000000</color><color name="gray">#D1D0CE</color><color name="background_color">#E1E2E2</color><color name="primary">#3f51b5</color><color name="primary_pressed">#E1E2E2</color><color name="primary_dark">#303f9f</color><color name="ripple">#F06292</color><color name="red">#FF0000</color><color name="cyan">#00FFFF</color><color name="lightBlue">#ADD8E6</color><color name="text_color">#686868</color><color name="android_text_color">#747474</color><color name="app_topbar_color">#AAAAAA</color><color name="list_even">#AAAAAA</color><color name="list_odd">#E1E2E2</color><color name="list_selected">#455FB6</color><color name="list_header">#99979C</color></file><file path="E:\LorealBa-Latest-2024\LorealBa-Latest-2024\library\src\main\res\values\dimens.xml" qualifiers=""><dimen name="activity_horizontal_margin">16dp</dimen><dimen name="activity_vertical_margin">16dp</dimen></file><file path="E:\LorealBa-Latest-2024\LorealBa-Latest-2024\library\src\main\res\values\strings.xml" qualifiers=""><string name="type_to_search">Type to Search</string></file><file path="E:\LorealBa-Latest-2024\LorealBa-Latest-2024\library\src\main\res\values\styles.xml" qualifiers=""><style name="MaterialSpinner" parent="Widget.AppCompat.Spinner">
<item name="rd_style">@style/Material.Drawable.Ripple.Wave.Light</item>
<item name="spn_labelEnable">true</item>
<item name="spn_labelTextSize">18sp</item>
<item name="spn_arrowSwitchMode">true</item>
<item name="spn_arrowAnimDuration">@android:integer/config_shortAnimTime</item>
<item name="spn_arrowInterpolator">@android:anim/decelerate_interpolator</item>
</style><style name="myDialog" parent="@android:style/Theme.Holo.Light.Dialog">
<item name="android:windowTitleStyle">@style/myDialogTitle</item>
</style><style name="myDialogTitle" parent="@android:style/TextAppearance.DialogWindowTitle">
<item name="android:gravity">center_horizontal</item>
</style><style name="DialogWindowTitle">
<item name="android:maxLines">1</item>
<item name="android:scrollHorizontally">true</item>
<item name="android:textAppearance">@android:style/TextAppearance.DialogWindowTitle</item>
</style></file><file path="E:\LorealBa-Latest-2024\LorealBa-Latest-2024\library\src\main\res\values-v21\attrs.xml" qualifiers="v21"><declare-styleable name="MultiSpinnerSearch">
<attr format="string" name="hintText"/>
</declare-styleable></file><file path="E:\LorealBa-Latest-2024\LorealBa-Latest-2024\library\src\main\res\values-v21\styles.xml" qualifiers="v21"><style name="MaterialSpinner" parent="Material.Widget.Spinner">
<item name="rd_style">@style/Material.Drawable.Ripple.Wave.Light</item>
<item name="spn_labelEnable">true</item>
<item name="spn_labelTextSize">18sp</item>
<item name="spn_arrowSwitchMode">true</item>
<item name="spn_arrowAnimDuration">@android:integer/config_shortAnimTime</item>
<item name="spn_arrowInterpolator">@android:anim/decelerate_interpolator</item>
</style><style name="myDialog" parent="@android:style/Theme.Holo.Light.Dialog">
<item name="android:windowTitleStyle">@style/myDialogTitle</item>
</style><style name="myDialogTitle" parent="@android:style/TextAppearance.DialogWindowTitle">
<item name="android:gravity">center_horizontal</item>
</style><style name="DialogWindowTitle">
<item name="android:maxLines">1</item>
<item name="android:scrollHorizontally">true</item>
<item name="android:textAppearance">@android:style/TextAppearance.DialogWindowTitle</item>
</style></file></source></dataSet><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="debug$Generated" generated="true" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="E:\LorealBa-Latest-2024\LorealBa-Latest-2024\library\src\debug\res"/></dataSet><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="debug" generated-set="debug$Generated" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="E:\LorealBa-Latest-2024\LorealBa-Latest-2024\library\src\debug\res"/></dataSet><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="generated$Generated" generated="true" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="E:\LorealBa-Latest-2024\LorealBa-Latest-2024\library\build\generated\res\resValues\debug"/></dataSet><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="generated" generated-set="generated$Generated" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="E:\LorealBa-Latest-2024\LorealBa-Latest-2024\library\build\generated\res\resValues\debug"/></dataSet><mergedItems/></merger>

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