AutomaticCaptureLocationProvider.cs 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. /*===============================================================================
  2. Copyright (C) 2022 Immersal - Part of Hexagon. All Rights Reserved.
  3. This file is part of the Immersal SDK.
  4. The Immersal SDK cannot be copied, distributed, or made available to
  5. third-parties for commercial purposes without written permission of Immersal Ltd.
  6. Contact sdk@immersal.com for licensing requests.
  7. ===============================================================================*/
  8. using UnityEngine;
  9. using System.Collections;
  10. using Immersal.Samples.Mapping;
  11. #if PLATFORM_ANDROID
  12. using UnityEngine.Android;
  13. #endif
  14. namespace Immersal.Samples.Mapping
  15. {
  16. public class AutomaticCaptureLocationProvider : MonoBehaviour
  17. {
  18. public double latitude { get; private set; } = 0.0;
  19. public double longitude { get; private set; } = 0.0;
  20. public double altitude { get; private set; } = 0.0;
  21. public bool gpsOn
  22. {
  23. #if (UNITY_IOS || PLATFORM_ANDROID) && !UNITY_EDITOR
  24. get { return NativeBindings.LocationServicesEnabled(); }
  25. #else
  26. get
  27. {
  28. return Input.location.status == LocationServiceStatus.Running;
  29. }
  30. #endif
  31. }
  32. public static AutomaticCaptureLocationProvider Instance
  33. {
  34. get
  35. {
  36. #if UNITY_EDITOR
  37. if (instance == null && !Application.isPlaying)
  38. {
  39. instance = UnityEngine.Object.FindObjectOfType<AutomaticCaptureLocationProvider>();
  40. }
  41. #endif
  42. if (instance == null)
  43. {
  44. Debug.LogError("No AutomaticCaptureLocationProvider instance found. Ensure one exists in the scene.");
  45. }
  46. return instance;
  47. }
  48. }
  49. private static AutomaticCaptureLocationProvider instance = null;
  50. void Awake()
  51. {
  52. if (instance == null)
  53. {
  54. instance = this;
  55. }
  56. if (instance != this)
  57. {
  58. Debug.LogError("There must be only one AutomaticCaptureLocationProvider object in a scene.");
  59. UnityEngine.Object.DestroyImmediate(this);
  60. return;
  61. }
  62. }
  63. private void Start()
  64. {
  65. #if UNITY_IOS
  66. StartCoroutine(EnableLocationServices());
  67. #elif PLATFORM_ANDROID
  68. if (Permission.HasUserAuthorizedPermission(Permission.FineLocation))
  69. {
  70. Debug.Log("Location permission OK");
  71. StartCoroutine(EnableLocationServices());
  72. }
  73. else
  74. {
  75. Debug.Log("Requesting location permission");
  76. Permission.RequestUserPermission(Permission.FineLocation);
  77. StartCoroutine(WaitForLocationPermission());
  78. }
  79. #endif
  80. }
  81. private void Update()
  82. {
  83. UpdateLocation();
  84. }
  85. private void UpdateLocation()
  86. {
  87. if (gpsOn)
  88. {
  89. #if (UNITY_IOS || PLATFORM_ANDROID) && !UNITY_EDITOR
  90. latitude = NativeBindings.GetLatitude();
  91. longitude = NativeBindings.GetLongitude();
  92. altitude = NativeBindings.GetAltitude();
  93. #else
  94. latitude = Input.location.lastData.latitude;
  95. longitude = Input.location.lastData.longitude;
  96. altitude = Input.location.lastData.altitude;
  97. #endif
  98. }
  99. }
  100. #if PLATFORM_ANDROID
  101. private IEnumerator WaitForLocationPermission()
  102. {
  103. while (!Permission.HasUserAuthorizedPermission(Permission.FineLocation))
  104. {
  105. yield return null;
  106. }
  107. Debug.Log("Location permission OK");
  108. StartCoroutine(EnableLocationServices());
  109. yield return null;
  110. }
  111. #endif
  112. private IEnumerator EnableLocationServices()
  113. {
  114. // First, check if user has location service enabled
  115. if (!Input.location.isEnabledByUser)
  116. {
  117. NotificationManager.Instance.GenerateNotification("Location services not enabled");
  118. Debug.Log("Location services not enabled");
  119. yield break;
  120. }
  121. // Start service before querying location
  122. #if (UNITY_IOS || PLATFORM_ANDROID) && !UNITY_EDITOR
  123. NativeBindings.StartLocation();
  124. #else
  125. Input.location.Start(0.001f, 0.001f);
  126. #endif
  127. // Wait until service initializes
  128. int maxWait = 20;
  129. #if (UNITY_IOS || PLATFORM_ANDROID) && !UNITY_EDITOR
  130. while (!NativeBindings.LocationServicesEnabled() && maxWait > 0)
  131. #else
  132. while (Input.location.status == LocationServiceStatus.Initializing && maxWait > 0)
  133. #endif
  134. {
  135. yield return new WaitForSeconds(1);
  136. maxWait--;
  137. }
  138. // Service didn't initialize in 20 seconds
  139. if (maxWait < 1)
  140. {
  141. NotificationManager.Instance.GenerateNotification("Location services timed out");
  142. Debug.Log("Timed out");
  143. yield break;
  144. }
  145. // Connection has failed
  146. #if (UNITY_IOS || PLATFORM_ANDROID) && !UNITY_EDITOR
  147. if (!NativeBindings.LocationServicesEnabled())
  148. #else
  149. if (Input.location.status == LocationServiceStatus.Failed)
  150. #endif
  151. {
  152. NotificationManager.Instance.GenerateNotification("Unable to determine device location");
  153. Debug.Log("Unable to determine device location");
  154. yield break;
  155. }
  156. #if (UNITY_IOS || PLATFORM_ANDROID) && !UNITY_EDITOR
  157. if (NativeBindings.LocationServicesEnabled())
  158. #else
  159. if (Input.location.status == LocationServiceStatus.Running)
  160. #endif
  161. {
  162. //NotificationManager.Instance.GenerateNotification("Tracking geolocation");
  163. }
  164. }
  165. }
  166. }