Update location getting method for Android
This commit is contained in:
@@ -1,13 +1,11 @@
|
|||||||
/**
|
/**
|
||||||
* Enhanced Android Location Fix - Separate Module
|
* Android Location Fix - GPS + IP Geolocation Only
|
||||||
* File: static/js/android_location_handler.js
|
* File: static/js/android_location_handler.js
|
||||||
*
|
*
|
||||||
* This module addresses Android-specific geolocation issues:
|
* This version includes only precise location methods:
|
||||||
* 1. Android Chrome timeout handling
|
* 1. Progressive GPS fallback (4 attempts)
|
||||||
* 2. Progressive fallback strategy
|
* 2. IP-based geolocation (3 services) - 5-50km accuracy
|
||||||
* 3. Enhanced permission detection
|
* No timezone analysis (removed 100km accuracy method)
|
||||||
* 4. Network location fallback
|
|
||||||
* 5. Multiple retry attempts with different configurations
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Android-specific geolocation configuration
|
// Android-specific geolocation configuration
|
||||||
@@ -15,46 +13,52 @@ const ANDROID_LOCATION_CONFIG = {
|
|||||||
// Primary attempt - High accuracy with reasonable timeout
|
// Primary attempt - High accuracy with reasonable timeout
|
||||||
highAccuracy: {
|
highAccuracy: {
|
||||||
enableHighAccuracy: true,
|
enableHighAccuracy: true,
|
||||||
timeout: 15000, // Increased from 10000 for Android
|
timeout: 15000,
|
||||||
maximumAge: 60000 // Reduced cache time for fresh location
|
maximumAge: 60000
|
||||||
},
|
},
|
||||||
|
|
||||||
// Fallback attempt - Network-based location
|
// Fallback attempt - Network-based location
|
||||||
networkBased: {
|
networkBased: {
|
||||||
enableHighAccuracy: false,
|
enableHighAccuracy: false,
|
||||||
timeout: 20000, // Longer timeout for network-based
|
timeout: 20000,
|
||||||
maximumAge: 300000
|
maximumAge: 300000
|
||||||
},
|
},
|
||||||
|
|
||||||
// Final attempt - Any available location
|
// Final attempt - Any available location
|
||||||
anyLocation: {
|
anyLocation: {
|
||||||
enableHighAccuracy: false,
|
enableHighAccuracy: false,
|
||||||
timeout: 30000, // Maximum patience for Android
|
timeout: 30000,
|
||||||
maximumAge: 600000
|
maximumAge: 600000
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Enhanced location request with Android-specific handling
|
// Global variables for location state
|
||||||
|
let locationAttemptInProgress = false;
|
||||||
|
let currentLocationMethod = '';
|
||||||
|
|
||||||
|
// Enhanced location request with GPS + IP fallback only
|
||||||
function requestAndroidEnhancedLocation() {
|
function requestAndroidEnhancedLocation() {
|
||||||
console.log("📱 Starting Android-enhanced location request...");
|
console.log("📱 Starting Android location request (GPS + IP methods only)...");
|
||||||
|
|
||||||
|
if (locationAttemptInProgress) {
|
||||||
|
console.log("📍 Location attempt already in progress, skipping");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (typeof locationRequestActive !== 'undefined' && locationRequestActive) {
|
if (typeof locationRequestActive !== 'undefined' && locationRequestActive) {
|
||||||
console.log("📍 Location request already active, skipping Android enhancement");
|
console.log("📍 Location request already active, skipping");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!navigator.geolocation) {
|
if (!navigator.geolocation) {
|
||||||
console.log("❌ Geolocation not supported");
|
console.log("❌ Geolocation not supported, trying IP-based location");
|
||||||
if (typeof userLocation !== 'undefined') {
|
attemptIPBasedLocation();
|
||||||
userLocation.source = "manual";
|
|
||||||
}
|
|
||||||
if (typeof currentUserLocation !== 'undefined') {
|
|
||||||
currentUserLocation.source = "manual";
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set active flag
|
locationAttemptInProgress = true;
|
||||||
|
|
||||||
|
// Set active flags
|
||||||
if (typeof locationRequestActive !== 'undefined') {
|
if (typeof locationRequestActive !== 'undefined') {
|
||||||
locationRequestActive = true;
|
locationRequestActive = true;
|
||||||
}
|
}
|
||||||
@@ -62,19 +66,18 @@ function requestAndroidEnhancedLocation() {
|
|||||||
locationCaptureActive = true;
|
locationCaptureActive = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("📱 Attempting Android-optimized location sequence...");
|
console.log("📱 Attempting GPS-based location sequence...");
|
||||||
|
|
||||||
// Start progressive location attempts
|
|
||||||
attemptAndroidLocationSequence();
|
attemptAndroidLocationSequence();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GPS-based sequence (Steps 1-4)
|
||||||
function attemptAndroidLocationSequence() {
|
function attemptAndroidLocationSequence() {
|
||||||
console.log("🔄 Android Location Sequence - Attempt 1: High Accuracy GPS");
|
console.log("🔄 Step 1/5: High Accuracy GPS");
|
||||||
|
currentLocationMethod = 'gps_high_accuracy';
|
||||||
|
|
||||||
// Attempt 1: High accuracy with Android-optimized timeout
|
|
||||||
navigator.geolocation.getCurrentPosition(
|
navigator.geolocation.getCurrentPosition(
|
||||||
(position) => {
|
(position) => {
|
||||||
console.log("✅ Android high-accuracy location success!");
|
console.log("✅ GPS high-accuracy success!");
|
||||||
handleAndroidLocationSuccess(position, "gps_high_accuracy");
|
handleAndroidLocationSuccess(position, "gps_high_accuracy");
|
||||||
},
|
},
|
||||||
(error) => {
|
(error) => {
|
||||||
@@ -86,11 +89,12 @@ function attemptAndroidLocationSequence() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function attemptNetworkBasedLocation() {
|
function attemptNetworkBasedLocation() {
|
||||||
console.log("🔄 Android Location Sequence - Attempt 2: Network-based");
|
console.log("🔄 Step 2/5: Network-based GPS");
|
||||||
|
currentLocationMethod = 'network';
|
||||||
|
|
||||||
navigator.geolocation.getCurrentPosition(
|
navigator.geolocation.getCurrentPosition(
|
||||||
(position) => {
|
(position) => {
|
||||||
console.log("✅ Android network-based location success!");
|
console.log("✅ Network-based GPS success!");
|
||||||
handleAndroidLocationSuccess(position, "network");
|
handleAndroidLocationSuccess(position, "network");
|
||||||
},
|
},
|
||||||
(error) => {
|
(error) => {
|
||||||
@@ -102,15 +106,16 @@ function attemptNetworkBasedLocation() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function attemptAnyAvailableLocation() {
|
function attemptAnyAvailableLocation() {
|
||||||
console.log("🔄 Android Location Sequence - Attempt 3: Any available");
|
console.log("🔄 Step 3/5: Any available GPS");
|
||||||
|
currentLocationMethod = 'any';
|
||||||
|
|
||||||
navigator.geolocation.getCurrentPosition(
|
navigator.geolocation.getCurrentPosition(
|
||||||
(position) => {
|
(position) => {
|
||||||
console.log("✅ Android any-location success!");
|
console.log("✅ Any-location GPS success!");
|
||||||
handleAndroidLocationSuccess(position, "any");
|
handleAndroidLocationSuccess(position, "any");
|
||||||
},
|
},
|
||||||
(error) => {
|
(error) => {
|
||||||
console.log(`❌ All location attempts failed (${error.message}), trying watchPosition...`);
|
console.log(`❌ Any location failed (${error.message}), trying watchPosition...`);
|
||||||
attemptWatchPosition();
|
attemptWatchPosition();
|
||||||
},
|
},
|
||||||
ANDROID_LOCATION_CONFIG.anyLocation
|
ANDROID_LOCATION_CONFIG.anyLocation
|
||||||
@@ -118,50 +123,189 @@ function attemptAnyAvailableLocation() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function attemptWatchPosition() {
|
function attemptWatchPosition() {
|
||||||
console.log("🔄 Android Location Sequence - Attempt 4: Watch Position (single shot)");
|
console.log("🔄 Step 4/5: Watch Position (persistent)");
|
||||||
|
currentLocationMethod = 'watch';
|
||||||
|
|
||||||
let watchId = null;
|
let watchId = null;
|
||||||
let watchTimeout = null;
|
let watchTimeout = null;
|
||||||
|
|
||||||
// Set timeout for watch attempt
|
|
||||||
watchTimeout = setTimeout(() => {
|
watchTimeout = setTimeout(() => {
|
||||||
if (watchId !== null) {
|
if (watchId !== null) {
|
||||||
navigator.geolocation.clearWatch(watchId);
|
navigator.geolocation.clearWatch(watchId);
|
||||||
}
|
}
|
||||||
console.log("❌ Watch position timed out, location failed");
|
console.log("❌ Watch position timed out, trying IP-based location...");
|
||||||
handleAndroidLocationError("All location methods failed");
|
attemptIPBasedLocation();
|
||||||
}, 25000);
|
}, 25000);
|
||||||
|
|
||||||
// Use watchPosition for more persistent location tracking
|
|
||||||
watchId = navigator.geolocation.watchPosition(
|
watchId = navigator.geolocation.watchPosition(
|
||||||
(position) => {
|
(position) => {
|
||||||
console.log("✅ Android watch position success!");
|
console.log("✅ Watch position success!");
|
||||||
|
|
||||||
// Clear watch and timeout
|
|
||||||
navigator.geolocation.clearWatch(watchId);
|
navigator.geolocation.clearWatch(watchId);
|
||||||
clearTimeout(watchTimeout);
|
clearTimeout(watchTimeout);
|
||||||
|
|
||||||
handleAndroidLocationSuccess(position, "watch");
|
handleAndroidLocationSuccess(position, "watch");
|
||||||
},
|
},
|
||||||
(error) => {
|
(error) => {
|
||||||
console.log(`❌ Watch position error: ${error.message}`);
|
console.log(`❌ Watch position error: ${error.message}`);
|
||||||
// Don't clear watch immediately, let timeout handle it
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
enableHighAccuracy: false,
|
enableHighAccuracy: false,
|
||||||
timeout: 20000,
|
timeout: 20000,
|
||||||
maximumAge: 0 // Force fresh location
|
maximumAge: 0
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IP-based geolocation (Step 5) - Final fallback
|
||||||
|
function attemptIPBasedLocation() {
|
||||||
|
console.log("🔄 Step 5/5: IP-based Geolocation (Final Fallback)");
|
||||||
|
currentLocationMethod = 'ip_geolocation';
|
||||||
|
|
||||||
|
// Try multiple IP geolocation services for better accuracy
|
||||||
|
const ipLocationServices = [
|
||||||
|
{
|
||||||
|
url: 'https://ipapi.co/json/',
|
||||||
|
parseResponse: (data) => ({
|
||||||
|
lat: data.latitude,
|
||||||
|
lng: data.longitude,
|
||||||
|
city: data.city,
|
||||||
|
region: data.region,
|
||||||
|
country: data.country_name,
|
||||||
|
accuracy: data.city ? 10000 : 50000 // Better accuracy if city is available
|
||||||
|
})
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: 'https://ip-api.com/json/',
|
||||||
|
parseResponse: (data) => ({
|
||||||
|
lat: data.lat,
|
||||||
|
lng: data.lon,
|
||||||
|
city: data.city,
|
||||||
|
region: data.regionName,
|
||||||
|
country: data.country,
|
||||||
|
accuracy: data.city ? 10000 : 50000 // Better accuracy if city is available
|
||||||
|
})
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: 'https://ipinfo.io/json',
|
||||||
|
parseResponse: (data) => {
|
||||||
|
if (data.loc) {
|
||||||
|
const [lat, lng] = data.loc.split(',');
|
||||||
|
return {
|
||||||
|
lat: parseFloat(lat),
|
||||||
|
lng: parseFloat(lng),
|
||||||
|
city: data.city,
|
||||||
|
region: data.region,
|
||||||
|
country: data.country,
|
||||||
|
accuracy: data.city ? 15000 : 50000 // Better accuracy if city is available
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
let serviceIndex = 0;
|
||||||
|
|
||||||
|
function tryNextIPService() {
|
||||||
|
if (serviceIndex >= ipLocationServices.length) {
|
||||||
|
console.log("❌ All IP geolocation services failed - location detection complete");
|
||||||
|
handleAndroidLocationError("All GPS and IP geolocation methods failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const service = ipLocationServices[serviceIndex];
|
||||||
|
console.log(`🌐 Trying IP geolocation service ${serviceIndex + 1}: ${service.url}`);
|
||||||
|
|
||||||
|
const controller = new AbortController();
|
||||||
|
const timeoutId = setTimeout(() => controller.abort(), 10000);
|
||||||
|
|
||||||
|
fetch(service.url, {
|
||||||
|
method: 'GET',
|
||||||
|
signal: controller.signal,
|
||||||
|
headers: {
|
||||||
|
'Accept': 'application/json'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
clearTimeout(timeoutId);
|
||||||
|
console.log(`🌐 IP service ${serviceIndex + 1} response:`, data);
|
||||||
|
|
||||||
|
const parsed = service.parseResponse(data);
|
||||||
|
|
||||||
|
if (parsed && parsed.lat && parsed.lng && !isNaN(parsed.lat) && !isNaN(parsed.lng)) {
|
||||||
|
// Validate coordinates are reasonable
|
||||||
|
if (parsed.lat >= -90 && parsed.lat <= 90 && parsed.lng >= -180 && parsed.lng <= 180) {
|
||||||
|
console.log(`✅ IP-based location success: ${parsed.lat}, ${parsed.lng}`);
|
||||||
|
console.log(`📊 Location: ${parsed.city}, ${parsed.region}, ${parsed.country}`);
|
||||||
|
console.log(`📊 Estimated accuracy: ${parsed.accuracy}m (~${Math.round(parsed.accuracy/1000)}km)`);
|
||||||
|
|
||||||
|
const ipLocationData = {
|
||||||
|
coords: {
|
||||||
|
latitude: parsed.lat,
|
||||||
|
longitude: parsed.lng,
|
||||||
|
accuracy: parsed.accuracy,
|
||||||
|
altitude: null
|
||||||
|
},
|
||||||
|
locationInfo: {
|
||||||
|
city: parsed.city,
|
||||||
|
region: parsed.region,
|
||||||
|
country: parsed.country,
|
||||||
|
source: `IP Service ${serviceIndex + 1}`,
|
||||||
|
serviceUrl: service.url
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
handleAndroidLocationSuccess(ipLocationData, "ip_geolocation");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`❌ Invalid or missing coordinates from service ${serviceIndex + 1}, trying next...`);
|
||||||
|
serviceIndex++;
|
||||||
|
tryNextIPService();
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
clearTimeout(timeoutId);
|
||||||
|
if (error.name === 'AbortError') {
|
||||||
|
console.log(`❌ IP service ${serviceIndex + 1} timed out (10s), trying next...`);
|
||||||
|
} else {
|
||||||
|
console.log(`❌ IP service ${serviceIndex + 1} failed: ${error.message}, trying next...`);
|
||||||
|
}
|
||||||
|
serviceIndex++;
|
||||||
|
tryNextIPService();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
tryNextIPService();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enhanced success handler for GPS and IP location methods
|
||||||
function handleAndroidLocationSuccess(position, source) {
|
function handleAndroidLocationSuccess(position, source) {
|
||||||
console.log(`✅ Android location obtained successfully via ${source}`);
|
console.log(`✅ Android location obtained successfully via ${source}`);
|
||||||
console.log(`📍 Coordinates: ${position.coords.latitude}, ${position.coords.longitude}`);
|
|
||||||
console.log(`📊 Accuracy: ${position.coords.accuracy}m`);
|
|
||||||
|
|
||||||
// Create location object
|
let locationData;
|
||||||
const locationData = {
|
|
||||||
|
if (source === "ip_geolocation") {
|
||||||
|
// Handle IP-based location
|
||||||
|
locationData = {
|
||||||
|
latitude: position.coords.latitude,
|
||||||
|
longitude: position.coords.longitude,
|
||||||
|
accuracy: position.coords.accuracy,
|
||||||
|
altitude: position.coords.altitude,
|
||||||
|
timestamp: new Date(),
|
||||||
|
source: source,
|
||||||
|
address: null,
|
||||||
|
locationInfo: position.locationInfo || null
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log(`📍 IP-estimated coordinates: ${position.coords.latitude}, ${position.coords.longitude}`);
|
||||||
|
console.log(`📊 IP-estimated accuracy: ${position.coords.accuracy}m (~${Math.round(position.coords.accuracy/1000)}km)`);
|
||||||
|
if (position.locationInfo) {
|
||||||
|
console.log(`🏢 Location info: ${position.locationInfo.city}, ${position.locationInfo.region}`);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Handle GPS-based location
|
||||||
|
locationData = {
|
||||||
latitude: position.coords.latitude,
|
latitude: position.coords.latitude,
|
||||||
longitude: position.coords.longitude,
|
longitude: position.coords.longitude,
|
||||||
accuracy: position.coords.accuracy,
|
accuracy: position.coords.accuracy,
|
||||||
@@ -171,24 +315,28 @@ function handleAndroidLocationSuccess(position, source) {
|
|||||||
address: null,
|
address: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Update global location variables based on what's available
|
console.log(`📍 GPS coordinates: ${position.coords.latitude}, ${position.coords.longitude}`);
|
||||||
|
console.log(`📊 GPS accuracy: ${position.coords.accuracy}m`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update global location variables
|
||||||
if (typeof userLocation !== 'undefined') {
|
if (typeof userLocation !== 'undefined') {
|
||||||
Object.assign(userLocation, locationData);
|
Object.assign(userLocation, locationData);
|
||||||
console.log("📍 Updated userLocation with Android data");
|
console.log("📍 Updated userLocation with location data");
|
||||||
|
|
||||||
// Trigger reverse geocoding if function exists
|
// Trigger reverse geocoding if we have coordinates but no address
|
||||||
if (typeof reverseGeocode === 'function') {
|
if (typeof reverseGeocode === 'function' && locationData.latitude && locationData.longitude && !locationData.address) {
|
||||||
reverseGeocode(userLocation.latitude, userLocation.longitude);
|
reverseGeocode(locationData.latitude, locationData.longitude);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof currentUserLocation !== 'undefined') {
|
if (typeof currentUserLocation !== 'undefined') {
|
||||||
Object.assign(currentUserLocation, locationData);
|
Object.assign(currentUserLocation, locationData);
|
||||||
console.log("📍 Updated currentUserLocation with Android data");
|
console.log("📍 Updated currentUserLocation with location data");
|
||||||
|
|
||||||
// Trigger enhanced reverse geocoding if function exists
|
// Trigger enhanced reverse geocoding if available
|
||||||
if (typeof reverseGeocodeEnhanced === 'function') {
|
if (typeof reverseGeocodeEnhanced === 'function' && locationData.latitude && locationData.longitude && !locationData.address) {
|
||||||
reverseGeocodeEnhanced(currentUserLocation.latitude, currentUserLocation.longitude);
|
reverseGeocodeEnhanced(locationData.latitude, locationData.longitude);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,19 +347,24 @@ function handleAndroidLocationSuccess(position, source) {
|
|||||||
if (typeof locationCaptureActive !== 'undefined') {
|
if (typeof locationCaptureActive !== 'undefined') {
|
||||||
locationCaptureActive = false;
|
locationCaptureActive = false;
|
||||||
}
|
}
|
||||||
|
locationAttemptInProgress = false;
|
||||||
|
|
||||||
// Log success for monitoring
|
// Console logging
|
||||||
logLocationAction('android_location_success', {
|
console.log(`📊 LOCATION SUCCESS LOG:`, {
|
||||||
source: source,
|
method: source,
|
||||||
accuracy: position.coords.accuracy,
|
success: true,
|
||||||
coordinates: `${position.coords.latitude},${position.coords.longitude}`
|
coordinates: `${locationData.latitude},${locationData.longitude}`,
|
||||||
|
accuracy: `${locationData.accuracy}m`,
|
||||||
|
accuracyKm: `~${Math.round(locationData.accuracy/1000)}km`,
|
||||||
|
locationInfo: locationData.locationInfo,
|
||||||
|
timestamp: new Date().toISOString()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleAndroidLocationError(errorMessage) {
|
function handleAndroidLocationError(errorMessage) {
|
||||||
console.log(`❌ Android location error: ${errorMessage}`);
|
console.log(`❌ All Android location methods failed: ${errorMessage}`);
|
||||||
|
|
||||||
// Update global location variables
|
// Update global location variables to indicate manual source
|
||||||
if (typeof userLocation !== 'undefined') {
|
if (typeof userLocation !== 'undefined') {
|
||||||
userLocation.source = "manual";
|
userLocation.source = "manual";
|
||||||
}
|
}
|
||||||
@@ -226,69 +379,40 @@ function handleAndroidLocationError(errorMessage) {
|
|||||||
if (typeof locationCaptureActive !== 'undefined') {
|
if (typeof locationCaptureActive !== 'undefined') {
|
||||||
locationCaptureActive = false;
|
locationCaptureActive = false;
|
||||||
}
|
}
|
||||||
|
locationAttemptInProgress = false;
|
||||||
|
|
||||||
// Log error for monitoring
|
console.log(`📊 LOCATION ERROR LOG:`, {
|
||||||
logLocationAction('android_location_error', {
|
|
||||||
error: errorMessage,
|
error: errorMessage,
|
||||||
userAgent: navigator.userAgent
|
method: currentLocationMethod,
|
||||||
|
finalResult: 'manual_entry_required',
|
||||||
|
gpsAttempts: 4,
|
||||||
|
ipAttempts: 3,
|
||||||
|
userAgent: navigator.userAgent,
|
||||||
|
timestamp: new Date().toISOString()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enhanced permission checking for Android
|
// Device detection functions
|
||||||
function checkAndroidLocationPermissions() {
|
|
||||||
console.log("📱 Checking Android location permissions...");
|
|
||||||
|
|
||||||
// Check if permissions API is available (newer Android browsers)
|
|
||||||
if ('permissions' in navigator) {
|
|
||||||
navigator.permissions.query({name: 'geolocation'}).then(function(result) {
|
|
||||||
console.log(`📱 Geolocation permission: ${result.state}`);
|
|
||||||
|
|
||||||
if (result.state === 'granted') {
|
|
||||||
console.log("✅ Android location permission granted");
|
|
||||||
requestAndroidEnhancedLocation();
|
|
||||||
} else if (result.state === 'prompt') {
|
|
||||||
console.log("⚠️ Android location permission will be prompted");
|
|
||||||
requestAndroidEnhancedLocation();
|
|
||||||
} else {
|
|
||||||
console.log("❌ Android location permission denied");
|
|
||||||
handleAndroidLocationError("Permission denied");
|
|
||||||
}
|
|
||||||
}).catch(function(error) {
|
|
||||||
console.log("⚠️ Could not check permissions, proceeding with location request");
|
|
||||||
requestAndroidEnhancedLocation();
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// Fallback for older Android browsers
|
|
||||||
console.log("📱 Permissions API not available, proceeding with location request");
|
|
||||||
requestAndroidEnhancedLocation();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Detect if device is Android
|
|
||||||
function isAndroidDevice() {
|
function isAndroidDevice() {
|
||||||
const userAgent = navigator.userAgent.toLowerCase();
|
const userAgent = navigator.userAgent.toLowerCase();
|
||||||
return userAgent.includes('android');
|
return userAgent.includes('android');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Detect if browser is Chrome on Android
|
|
||||||
function isAndroidChrome() {
|
function isAndroidChrome() {
|
||||||
const userAgent = navigator.userAgent.toLowerCase();
|
const userAgent = navigator.userAgent.toLowerCase();
|
||||||
return userAgent.includes('android') && userAgent.includes('chrome') && !userAgent.includes('edg');
|
return userAgent.includes('android') && userAgent.includes('chrome') && !userAgent.includes('edg');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enhanced location initialization for Android
|
// Main initialization function
|
||||||
function initializeAndroidLocation() {
|
function initializeAndroidLocation() {
|
||||||
console.log("📱 Initializing Android-enhanced location services...");
|
console.log("📱 Initializing Android location services (GPS + IP only)...");
|
||||||
|
|
||||||
if (isAndroidDevice()) {
|
if (isAndroidDevice()) {
|
||||||
console.log("📱 Android device detected, using enhanced location handling");
|
console.log("📱 Android device detected, using GPS + IP location methods (5 steps)");
|
||||||
|
requestAndroidEnhancedLocation();
|
||||||
// Use Android-specific permission checking
|
|
||||||
checkAndroidLocationPermissions();
|
|
||||||
} else {
|
} else {
|
||||||
console.log("📱 Non-Android device, using standard location request");
|
console.log("📱 Non-Android device, using standard location request");
|
||||||
|
|
||||||
// Fall back to standard location request
|
|
||||||
if (typeof requestLocationData === 'function') {
|
if (typeof requestLocationData === 'function') {
|
||||||
requestLocationData();
|
requestLocationData();
|
||||||
} else if (typeof requestEnhancedLocation === 'function') {
|
} else if (typeof requestEnhancedLocation === 'function') {
|
||||||
@@ -297,54 +421,22 @@ function initializeAndroidLocation() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Location action logging function
|
// Override standard location initialization for Android devices
|
||||||
function logLocationAction(action, data) {
|
|
||||||
try {
|
|
||||||
console.log(`📊 Location Action Log: ${action}`, data);
|
|
||||||
|
|
||||||
// Send to server for monitoring if endpoint exists
|
|
||||||
if (typeof fetch !== 'undefined') {
|
|
||||||
fetch('/api/log-location-action', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
action: action,
|
|
||||||
data: data,
|
|
||||||
timestamp: new Date().toISOString(),
|
|
||||||
userAgent: navigator.userAgent
|
|
||||||
})
|
|
||||||
}).catch(error => {
|
|
||||||
console.log('📊 Could not send location log to server:', error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.log('📊 Location logging error:', error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Override standard location initialization if this is an Android device
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
// Small delay to ensure other scripts are loaded
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (isAndroidDevice()) {
|
if (isAndroidDevice()) {
|
||||||
console.log("📱 Android detected - overriding standard location initialization");
|
console.log("📱 Android detected - overriding with GPS + IP location handler");
|
||||||
|
|
||||||
// Replace standard initialization with Android-enhanced version
|
|
||||||
if (typeof initializeLocation === 'function') {
|
if (typeof initializeLocation === 'function') {
|
||||||
const originalInitializeLocation = initializeLocation;
|
|
||||||
window.initializeLocation = function() {
|
window.initializeLocation = function() {
|
||||||
console.log("📱 Using Android-enhanced location initialization");
|
console.log("📱 Using GPS + IP Android location initialization");
|
||||||
initializeAndroidLocation();
|
initializeAndroidLocation();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Also handle the enhanced location capture
|
|
||||||
if (typeof requestEnhancedLocation === 'function') {
|
if (typeof requestEnhancedLocation === 'function') {
|
||||||
const originalRequestEnhanced = requestEnhancedLocation;
|
|
||||||
window.requestEnhancedLocation = function() {
|
window.requestEnhancedLocation = function() {
|
||||||
console.log("📱 Using Android-enhanced location request");
|
console.log("📱 Using GPS + IP Android location request");
|
||||||
initializeAndroidLocation();
|
initializeAndroidLocation();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -352,14 +444,13 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
}, 100);
|
}, 100);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Export functions for external use
|
// Export functions
|
||||||
if (typeof window !== 'undefined') {
|
if (typeof window !== 'undefined') {
|
||||||
window.AndroidLocationHandler = {
|
window.AndroidLocationHandler = {
|
||||||
requestAndroidEnhancedLocation,
|
requestAndroidEnhancedLocation,
|
||||||
checkAndroidLocationPermissions,
|
|
||||||
isAndroidDevice,
|
isAndroidDevice,
|
||||||
isAndroidChrome,
|
isAndroidChrome,
|
||||||
initializeAndroidLocation,
|
initializeAndroidLocation,
|
||||||
logLocationAction
|
attemptIPBasedLocation
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user