示例#1
0
    /// <summary>
    /// Savings the capture image.
    /// </summary>
    /// <returns>The capture image.</returns>
    IEnumerator SavingCaptureImage()
    {
        yield return(new WaitForEndOfFrame());

        string path         = Application.persistentDataPath + "/";
        string saveFileName = m_FileName + GetDateString() + m_FileType;

        byte[] jpgData = m_TempScreenShot.EncodeToJPG();

                #if UNITY_EDITOR
        File.WriteAllBytes(saveFileName, jpgData);
        yield return(new WaitForEndOfFrame());

        OnCompleteCapture();
#elif UNITY_ANDROID
        if (UniAndroidPermission.IsPermitted(AndroidPermission.WRITE_EXTERNAL_STORAGE))
        {
            NativeGallery.SaveImageToGallery(jpgData, "ARCoreList", "Screenshot ARCoreList {0}.jpg");
        }
        else
        {
            OnCaptureFailed();
        }
#endif
    }
示例#2
0
        /// <summary>
        /// Raises the click open gallery camera event.
        /// </summary>
        /// <param name="isCam">If set to <c>true</c> is cam.</param>
        public void OnClickOpenGalleryCamera(bool isCam)
        {
#if UNITY_ANDROID && !UNITY_EDITOR
            if (isCam == true)
            {
                if (UniAndroidPermission.IsPermitted(AndroidPermission.CAMERA) == false)
                {
                    UniAndroidPermission.RequestCameraPremission(AndroidPermission.CAMERA, cameraPermitOn, cameraPermitOff);
                }
                else
                {
                    AndroidJavaClass unityPlayer   = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
                    AndroidJavaClass galleryBinder = new AndroidJavaClass("com.gs.launchgallery.UnityBinder");
                    galleryBinder.CallStatic("openCameraGallery", unityPlayer.GetStatic <AndroidJavaObject>("currentActivity"), isCam);
                }
            }
            else
            {
                if (UniAndroidPermission.IsPermitted(AndroidPermission.WRITE_EXTERNAL_STORAGE) == false)
                {
                    UniAndroidPermission.RequestCameraPremission(AndroidPermission.WRITE_EXTERNAL_STORAGE, galleryPermitOn, galleryPermitOff);
                }
                else
                {
                    AndroidJavaClass unityPlayer   = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
                    AndroidJavaClass galleryBinder = new AndroidJavaClass("com.gs.launchgallery.UnityBinder");
                    galleryBinder.CallStatic("openCameraGallery", unityPlayer.GetStatic <AndroidJavaObject>("currentActivity"), isCam);
                }
            }
#endif
        }
示例#3
0
 public void requestPermission()
 {
     UniAndroidPermission.RequestPremission(AndroidPermission.ACCESS_COARSE_LOCATION, () => {
         // add permit action
     }, () => {
         // add not permit action
     });
 }
示例#4
0
 void RequestMicroPermission()
 {
     if (!UniAndroidPermission.IsPermitted(AndroidPermission.RECORD_AUDIO))
     {
         Debug.Log("RECORD_AUDIO NOT Permitted");
         UniAndroidPermission.RequestPermission(AndroidPermission.RECORD_AUDIO, RequestStoragePermission, null, null);
     }
 }
示例#5
0
 void RequestStoragePermission()
 {
     if (!UniAndroidPermission.IsPermitted(AndroidPermission.WRITE_EXTERNAL_STORAGE))
     {
         Debug.Log("WRITE_EXTERNAL_STORAGE NOT Permitted");
         UniAndroidPermission.RequestPermission(AndroidPermission.WRITE_EXTERNAL_STORAGE, null, null, null);
     }
 }
    public void RequestPermissionCall()
    {
        if (UniAndroidPermission.IsPermitted(AndroidPermission.CALL_PHONE))
        {
            return;
        }

        UniAndroidPermission.RequestPermission(AndroidPermission.CALL_PHONE);
    }
示例#7
0
    public void RequestReadPermission()
    {
        if (UniAndroidPermission.IsPermitted(AndroidPermission.READ_EXTERNAL_STORAGE))
        {
            return;
        }

        UniAndroidPermission.RequestPermission(AndroidPermission.READ_EXTERNAL_STORAGE, OnAllowCamRead, OnDenyRead, OnDenyAndNeverAskAgainRead);
    }
示例#8
0
    public void RequestWritePermission()
    {
        if (UniAndroidPermission.IsPermitted(AndroidPermission.WRITE_EXTERNAL_STORAGE))
        {
            return;
        }

        UniAndroidPermission.RequestPermission(AndroidPermission.WRITE_EXTERNAL_STORAGE, OnAllowWrite, OnDenyWrite, OnDenyAndNeverAskAgainWrite);
    }
示例#9
0
    public void RequestCameraPermission()
    {
        if (UniAndroidPermission.IsPermitted(AndroidPermission.CAMERA))
        {
            return;
        }

        UniAndroidPermission.RequestPermission(AndroidPermission.CAMERA, OnAllowCam, OnDenyCam, OnDenyAndNeverAskAgainCam);
    }
示例#10
0
    public void RequestPermissionSMS()
    {
        if (UniAndroidPermission.IsPermitted(AndroidPermission.SEND_SMS))
        {
            return;
        }

        UniAndroidPermission.RequestPermission(AndroidPermission.SEND_SMS);
    }
示例#11
0
    private string m_IPAddress = "192.168.107.1"; // Gear360:192.168.107.1 / Bublcam:192.168.0.100 / RICOH THETA:192.168.1.1

    void Start()
    {
        // infoデータをダウンロードしてみる
        //StartCoroutine(ExecGetInfo());
        //Capture();

        UniAndroidPermission.IsPermitted(AndroidPermission.WRITE_EXTERNAL_STORAGE);
        UniAndroidPermission.RequestPermission(AndroidPermission.WRITE_EXTERNAL_STORAGE, OnAllow, OnDeny, OnDenyAndNeverAskAgain);
    }
    public void RequestPermission()
    {
        if (UniAndroidPermission.IsPermitted(AndroidPermission.WRITE_EXTERNAL_STORAGE))
        {
            text.text = "WRITE_EXTERNAL_STORAGE is already permitted!!";
            return;
        }

        UniAndroidPermission.RequestPermission(AndroidPermission.WRITE_EXTERNAL_STORAGE, OnAllow, OnDeny, OnDenyAndNeverAskAgain);
    }
示例#13
0
    public void RequestPermission()
    {
        if (UniAndroidPermission.IsPermitted(AndroidPermission.ACCESS_FINE_LOCATION))
        {
            Another.SetActive(true);
            // text.text = "WRITE_EXTERNAL_STORAGE is already permitted!!";
            // Home.OnHuntingClick();
            //  Lifeless.pindah();
            return;
        }

        UniAndroidPermission.RequestPermission(AndroidPermission.ACCESS_FINE_LOCATION, OnAllow, OnDeny, OnDenyAndNeverAskAgain);
    }
    public void RequestPermission()
    {
        if (UniAndroidPermission.IsPermitted(AndroidPermission.WRITE_EXTERNAL_STORAGE))
        {
            Home.getGalery();
            // text.text = "WRITE_EXTERNAL_STORAGE is already permitted!!";
            // Home.OnHuntingClick();
            //  Lifeless.pindah();
            return;
        }

        UniAndroidPermission.RequestPermission(AndroidPermission.WRITE_EXTERNAL_STORAGE, OnAllow, OnDeny, OnDenyAndNeverAskAgain);
    }
示例#15
0
    public void RequestPermission()
    {
        if (UniAndroidPermission.IsPermitted(AndroidPermission.WRITE_EXTERNAL_STORAGE))
        {
            text.text = "WRITE_EXTERNAL_STORAGE is already permitted!!";
            return;
        }

        UniAndroidPermission.RequestPremission(AndroidPermission.WRITE_EXTERNAL_STORAGE, () => {
            text.text = "WRITE_EXTERNAL_STORAGE is permitted NOW!!";
        }, () => {
            text.text = "WRITE_EXTERNAL_STORAGE id NOT permitted...";
        });
    }
示例#16
0
    public void RequestPermission()
    {
        if (UniAndroidPermission.IsPermitted(AndroidPermission.ACCESS_FINE_LOCATION))
        {
            // text.text = "WRITE_EXTERNAL_STORAGE is already permitted!!";
            if (UniAndroidPermission.IsPermitted(AndroidPermission.CAMERA))
            {
                SceneManagerHelper.LoadScene("berburuhantu");

                // text.text = "CAMERA is already permitted!!";
                return;
            }
            UniAndroidPermission.RequestPermission(AndroidPermission.CAMERA, OnAllow2, OnDeny2, OnDenyAndNeverAskAgain2);
            return;
        }

        UniAndroidPermission.RequestPermission(AndroidPermission.ACCESS_FINE_LOCATION, OnAllow, OnDeny, OnDenyAndNeverAskAgain);
    }
    public void RequestPermission()
    {
        if (UniAndroidPermission.IsPermitted(AndroidPermission.ACCESS_FINE_LOCATION))
        {
            // text.text = "WRITE_EXTERNAL_STORAGE is already permitted!!";
            if (UniAndroidPermission.IsPermitted(AndroidPermission.CAMERA))
            {
                Home2.pindah();
                Home.OnHuntingClick();

                // text.text = "CAMERA is already permitted!!";
                return;
            }
            UniAndroidPermission.RequestPermission(AndroidPermission.CAMERA, OnAllow2, OnDeny2, OnDenyAndNeverAskAgain2);
            return;
        }

        UniAndroidPermission.RequestPermission(AndroidPermission.ACCESS_FINE_LOCATION, OnAllow, OnDeny, OnDenyAndNeverAskAgain);
    }
示例#18
0
    // Funcion que determina si la camara esta en espejo
    IEnumerator ComprobarCamara()
    {
        if (!UniAndroidPermission.IsPermitted(AndroidPermission.CAMERA))
        {
            UniAndroidPermission.RequestPermission(AndroidPermission.CAMERA);
        }



        // La rutina inicia la camara
        TexturaWebCam.Play();
        // Espera un segundo a que termine de cargar
        yield return(new WaitForSeconds(1));

//		print ("Comprobacion: " + TexturaWebCam.width + ", " + TexturaWebCam.height);
        // Una vez termina, comprueba si no esta en espejo...
        if (!TexturaWebCam.videoVerticallyMirrored)
        {
            // ... si lo esta, mantiene el giro por defecto
            ImagenCamara.transform.localEulerAngles = new Vector3(180, 0, 0);
//			Debug.Log ("NO espejo");
        }
        else
        {
            // ... si no lo esta, gira la imagen
            Debug.Log("SI espejo");
        }

        // Detiene la camara

        if (TexturaWebCam.width == TexturaWebCam.height)
        {
            Debug.Log("Cámara igual!");
        }

        TexturaWebCam.Stop();
        comprobacionHecha = true;
        GameObject.Find("LogIn").GetComponent <View> ().setCamaraChecked(true);
    }
示例#19
0
 void AccessCamera()
 {
     UniAndroidPermission.RequestPermission(AndroidPermission.CAMERA);
 }
示例#20
0
 private void OnAllow()
 {
     // text.text = "WRITE_EXTERNAL_STORAGE is permitted NOW!!";
     UniAndroidPermission.RequestPermission(AndroidPermission.CAMERA, OnAllow2, OnDeny2, OnDenyAndNeverAskAgain2);
 }
        /// <summary>
        /// Enable location and compass services.
        /// Sends continuous location and heading updates based on
        /// _desiredAccuracyInMeters and _updateDistanceInMeters.
        /// </summary>
        /// <returns>The location routine.</returns>
        IEnumerator PollLocationRoutine()
        {
#if UNITY_EDITOR
            while (!UnityEditor.EditorApplication.isRemoteConnected)
            {
                yield return(null);
            }
#endif


            //request runtime fine location permission on Android if not yet allowed
#if UNITY_ANDROID
            if (!Input.location.isEnabledByUser)
            {
                UniAndroidPermission.RequestPermission(AndroidPermission.ACCESS_FINE_LOCATION);
                //wait for user to allow or deny
                while (!_gotPermissionRequestResponse)
                {
                    yield return(_wait1sec);
                }
            }
#endif


            if (!Input.location.isEnabledByUser)
            {
                Debug.LogError("DeviceLocationProvider: Location is not enabled by user!");
                _currentLocation.IsLocationServiceEnabled = false;
                SendLocation(_currentLocation);
                yield break;
            }


            _currentLocation.IsLocationServiceInitializing = true;
            Input.location.Start(_desiredAccuracyInMeters, _updateDistanceInMeters);
            Input.compass.enabled = true;

            int maxWait = 20;
            while (Input.location.status == LocationServiceStatus.Initializing && maxWait > 0)
            {
                yield return(_wait1sec);

                maxWait--;
            }

            if (maxWait < 1)
            {
                Debug.LogError("DeviceLocationProvider: " + "Timed out trying to initialize location services!");
                _currentLocation.IsLocationServiceInitializing = false;
                _currentLocation.IsLocationServiceEnabled      = false;
                SendLocation(_currentLocation);
                yield break;
            }

            if (Input.location.status == LocationServiceStatus.Failed)
            {
                Debug.LogError("DeviceLocationProvider: " + "Failed to initialize location services!");
                _currentLocation.IsLocationServiceInitializing = false;
                _currentLocation.IsLocationServiceEnabled      = false;
                SendLocation(_currentLocation);
                yield break;
            }

            _currentLocation.IsLocationServiceInitializing = false;
            _currentLocation.IsLocationServiceEnabled      = true;

#if UNITY_EDITOR
            // HACK: this is to prevent Android devices, connected through Unity Remote,
            // from reporting a location of (0, 0), initially.
            yield return(_wait1sec);
#endif

            System.Globalization.CultureInfo invariantCulture = System.Globalization.CultureInfo.InvariantCulture;

            while (true)
            {
                _currentLocation.IsLocationServiceEnabled = Input.location.status == LocationServiceStatus.Running;

                _currentLocation.IsUserHeadingUpdated = false;
                _currentLocation.IsLocationUpdated    = false;

                if (!_currentLocation.IsLocationServiceEnabled)
                {
                    yield return(_waitUpdateTime);

                    continue;
                }

                // device orientation, user heading get calculated below
                _currentLocation.DeviceOrientation = Input.compass.trueHeading;


                var lastData  = Input.location.lastData;
                var timestamp = lastData.timestamp;
                //Debug.LogFormat("{0:yyyyMMdd-HHmmss} acc:{1:0.00} {2} / {3}", UnixTimestampUtils.From(timestamp), lastData.horizontalAccuracy, lastData.latitude, lastData.longitude);


                //_currentLocation.LatitudeLongitude = new Vector2d(lastData.latitude, lastData.longitude);
                // HACK to get back to double precision, does this even work?
                // https://forum.unity.com/threads/precision-of-location-longitude-is-worse-when-longitude-is-beyond-100-degrees.133192/#post-1835164
                double latitude  = double.Parse(lastData.latitude.ToString("R", invariantCulture), invariantCulture);
                double longitude = double.Parse(lastData.longitude.ToString("R", invariantCulture), invariantCulture);
                _currentLocation.LatitudeLongitude = new Vector2d(latitude, longitude);

                _currentLocation.Accuracy          = (int)System.Math.Floor(lastData.horizontalAccuracy);
                _currentLocation.IsLocationUpdated = timestamp > _lastLocationTimestamp;
                _currentLocation.Timestamp         = timestamp;
                _lastLocationTimestamp             = timestamp;

                if (_currentLocation.IsLocationUpdated)
                {
                    _lastPositions.Add(_currentLocation.LatitudeLongitude);
                }

                // calculate user heading. only if we have enough positions available
                if (_lastPositions.Count < _maxLastPositions)
                {
                    _currentLocation.UserHeading = 0;
                }
                else
                {
                    Vector2d   newestPos  = _lastPositions[0];
                    Vector2d   oldestPos  = _lastPositions[_maxLastPositions - 1];
                    CheapRuler cheapRuler = new CheapRuler(newestPos.x, CheapRulerUnits.Meters);
                    // distance between last and first position in our buffer
                    double distance = cheapRuler.Distance(
                        new double[] { newestPos.y, newestPos.x },
                        new double[] { oldestPos.y, oldestPos.x }
                        );
                    // positions are minimum required distance apart (user is moving), calculate user heading
                    if (distance >= _minDistanceOldestNewestPosition)
                    {
                        // calculate final heading from last positions but give newest headings more weight:
                        // '_lastPositions' contains newest at [0]
                        // formula:
                        // (heading[0] * e^weight[0] + heading[1] * e^weight[1] + .... ) / weight sum
                        float[] lastHeadings  = new float[_maxLastPositions - 1];
                        float[] actualWeights = new float[_maxLastPositions - 1];
                        float   finalHeading  = 0f;

                        for (int i = 1; i < _maxLastPositions; i++)
                        {
                            lastHeadings[i - 1] = (float)(Math.Atan2(_lastPositions[i].y - _lastPositions[i - 1].y, _lastPositions[i].x - _lastPositions[i - 1].x) * 180 / Math.PI);
                            // quick fix to take care of 355° and 5° being apart 10° and not 350°
                            if (lastHeadings[i - 1] > 180)
                            {
                                lastHeadings[i - 1] -= 360f;
                            }
                        }

                        for (int i = 0; i < lastHeadings.Length; i++)
                        {
                            actualWeights[i] = (float)Math.Exp(_headingWeights[i]);
                            finalHeading    += lastHeadings[i] * actualWeights[i];
                        }

                        float weightSum = actualWeights.Sum();
                        finalHeading /= weightSum;
                        // stay within [0..359] no negative angles
                        if (finalHeading < 0)
                        {
                            finalHeading += 360;
                        }

                        _currentLocation.UserHeading          = finalHeading;
                        _currentLocation.IsUserHeadingUpdated = true;
                    }
                }

                SendLocation(_currentLocation);

                yield return(_waitUpdateTime);
            }
        }
示例#22
0
    //Responsible for accessing the user location (Attach to TestLocationServicet GameObject)
    //note this sctipt is using preprocessor it is set to it will on run on mobile device and not on Unity editor

#if UNITY_ANDROID && !UNITY_EDITOR
    IEnumerator Start()
    {
        UniAndroidPermission.RequestPermission(AndroidPermission.ACCESS_FINE_LOCATION);
        yield return(null);
    }
        /// <summary>
        /// Enable location and compass services.
        /// Sends continuous location and heading updates based on
        /// _desiredAccuracyInMeters and _updateDistanceInMeters.
        /// </summary>
        /// <returns>The location routine.</returns>
        IEnumerator PollLocationRoutine()
        {
#if UNITY_EDITOR
            while (!UnityEditor.EditorApplication.isRemoteConnected)
            {
                yield return(null);
            }
#endif


            //request runtime fine location permission on Android if not yet allowed
#if UNITY_ANDROID
            if (!Input.location.isEnabledByUser)
            {
                UniAndroidPermission.RequestPermission(AndroidPermission.ACCESS_FINE_LOCATION);
                //wait for user to allow or deny
                while (!_gotPermissionRequestResponse)
                {
                    yield return(_wait1sec);
                }
            }
#endif


            if (!Input.location.isEnabledByUser)
            {
                Debug.LogError("DeviceLocationProvider: Location is not enabled by user!");
                _currentLocation.IsLocationServiceEnabled = false;
                SendLocation(_currentLocation);
                yield break;
            }


            _currentLocation.IsLocationServiceInitializing = true;
            Input.location.Start(_desiredAccuracyInMeters, _updateDistanceInMeters);
            Input.compass.enabled = true;

            int maxWait = 20;
            while (Input.location.status == LocationServiceStatus.Initializing && maxWait > 0)
            {
                yield return(_wait1sec);

                maxWait--;
            }

            if (maxWait < 1)
            {
                Debug.LogError("DeviceLocationProvider: " + "Timed out trying to initialize location services!");
                _currentLocation.IsLocationServiceInitializing = false;
                _currentLocation.IsLocationServiceEnabled      = false;
                SendLocation(_currentLocation);
                yield break;
            }

            if (Input.location.status == LocationServiceStatus.Failed)
            {
                Debug.LogError("DeviceLocationProvider: " + "Failed to initialize location services!");
                _currentLocation.IsLocationServiceInitializing = false;
                _currentLocation.IsLocationServiceEnabled      = false;
                SendLocation(_currentLocation);
                yield break;
            }

            _currentLocation.IsLocationServiceInitializing = false;
            _currentLocation.IsLocationServiceEnabled      = true;

#if UNITY_EDITOR
            // HACK: this is to prevent Android devices, connected through Unity Remote,
            // from reporting a location of (0, 0), initially.
            yield return(_wait1sec);
#endif


            float gpsInitializedTime = Time.realtimeSinceStartup;
            // initially pass through all locations that come available
            float gpsWarmupTime = 120f;             //seconds
            System.Globalization.CultureInfo invariantCulture = System.Globalization.CultureInfo.InvariantCulture;

            while (true)
            {
                _currentLocation.IsLocationServiceEnabled = true;

                _currentLocation.IsHeadingUpdated  = false;
                _currentLocation.IsLocationUpdated = false;

                var timestamp = Input.compass.timestamp;
                if (
                    Input.compass.enabled && timestamp > _lastHeadingTimestamp ||
                    Time.realtimeSinceStartup < gpsInitializedTime + gpsWarmupTime
                    )
                {
                    var heading = Input.compass.trueHeading;
                    _currentLocation.Heading         = heading;
                    _currentLocation.HeadingMagnetic = Input.compass.magneticHeading;
                    _currentLocation.HeadingAccuracy = Input.compass.headingAccuracy;
                    _lastHeadingTimestamp            = timestamp;

                    _currentLocation.IsHeadingUpdated = true;
                }

                var lastData = Input.location.lastData;
                timestamp = lastData.timestamp;
                //Debug.LogFormat("{0:yyyyMMdd-HHmmss} acc:{1:0.00} {2} / {3}", UnixTimestampUtils.From(timestamp), lastData.horizontalAccuracy, lastData.latitude, lastData.longitude);

                if (
                    (Input.location.status == LocationServiceStatus.Running && timestamp > _lastLocationTimestamp) ||
                    Time.realtimeSinceStartup < gpsInitializedTime + gpsWarmupTime
                    )
                {
                    //_currentLocation.LatitudeLongitude = new Vector2d(lastData.latitude, lastData.longitude);
                    // HACK to get back to double precision, does this even work?
                    // https://forum.unity.com/threads/precision-of-location-longitude-is-worse-when-longitude-is-beyond-100-degrees.133192/#post-1835164
                    double latitude  = double.Parse(lastData.latitude.ToString("R", invariantCulture), invariantCulture);
                    double longitude = double.Parse(lastData.longitude.ToString("R", invariantCulture), invariantCulture);
                    _currentLocation.LatitudeLongitude = new Vector2d(latitude, longitude);

                    _currentLocation.Accuracy  = (int)System.Math.Floor(lastData.horizontalAccuracy);
                    _currentLocation.Timestamp = timestamp;
                    _lastLocationTimestamp     = timestamp;

                    _currentLocation.IsLocationUpdated = true;
                }

                if (_currentLocation.IsHeadingUpdated || _currentLocation.IsLocationUpdated)
                {
                    if (_currentLocation.LatitudeLongitude != Vector2d.zero)
                    {
                        SendLocation(_currentLocation);
                    }
                }

                yield return(null);
            }
        }
        /// <summary>
        /// Enable location and compass services.
        /// Sends continuous location and heading updates based on
        /// _desiredAccuracyInMeters and _updateDistanceInMeters.
        /// </summary>
        /// <returns>The location routine.</returns>
        IEnumerator PollLocationRoutine()
        {
#if UNITY_EDITOR
            while (!UnityEditor.EditorApplication.isRemoteConnected)
            {
                // exit if we are not the selected location provider
                if (null != LocationProviderFactory.Instance && null != LocationProviderFactory.Instance.DefaultLocationProvider)
                {
                    if (!this.Equals(LocationProviderFactory.Instance.DefaultLocationProvider))
                    {
                        yield break;
                    }
                }

                Debug.LogWarning("Remote device not connected via 'Unity Remote'. Waiting ..." + Environment.NewLine + "If Unity seems to be stuck here make sure 'Unity Remote' is running and restart Unity with your device already connected.");
                yield return(_wait1sec);
            }
#endif


            //request runtime fine location permission on Android if not yet allowed
#if UNITY_ANDROID
            if (!_locationService.isEnabledByUser)
            {
                UniAndroidPermission.RequestPermission(AndroidPermission.ACCESS_FINE_LOCATION);
                //wait for user to allow or deny
                while (!_gotPermissionRequestResponse)
                {
                    yield return(_wait1sec);
                }
            }
#endif


            if (!_locationService.isEnabledByUser)
            {
                Debug.LogError("DeviceLocationProvider: Location is not enabled by user!");
                _currentLocation.IsLocationServiceEnabled = false;
                SendLocation(_currentLocation);
                yield break;
            }


            _currentLocation.IsLocationServiceInitializing = true;
            _locationService.Start(_desiredAccuracyInMeters, _updateDistanceInMeters);
            Input.compass.enabled = true;

            int maxWait = 20;
            while (_locationService.status == LocationServiceStatus.Initializing && maxWait > 0)
            {
                yield return(_wait1sec);

                maxWait--;
            }

            if (maxWait < 1)
            {
                Debug.LogError("DeviceLocationProvider: " + "Timed out trying to initialize location services!");
                _currentLocation.IsLocationServiceInitializing = false;
                _currentLocation.IsLocationServiceEnabled      = false;
                SendLocation(_currentLocation);
                yield break;
            }

            if (_locationService.status == LocationServiceStatus.Failed)
            {
                Debug.LogError("DeviceLocationProvider: " + "Failed to initialize location services!");
                _currentLocation.IsLocationServiceInitializing = false;
                _currentLocation.IsLocationServiceEnabled      = false;
                SendLocation(_currentLocation);
                yield break;
            }

            _currentLocation.IsLocationServiceInitializing = false;
            _currentLocation.IsLocationServiceEnabled      = true;

#if UNITY_EDITOR
            // HACK: this is to prevent Android devices, connected through Unity Remote,
            // from reporting a location of (0, 0), initially.
            yield return(_wait1sec);
#endif

            System.Globalization.CultureInfo invariantCulture = System.Globalization.CultureInfo.InvariantCulture;

            while (true)
            {
                var lastData  = _locationService.lastData;
                var timestamp = lastData.timestamp;

                ///////////////////////////////
                // oh boy, Unity what are you doing???
                // on some devices it seems that
                // Input.location.status != LocationServiceStatus.Running
                // nevertheless new location is available
                //////////////////////////////
                //Debug.LogFormat("Input.location.status: {0}", Input.location.status);
                _currentLocation.IsLocationServiceEnabled =
                    _locationService.status == LocationServiceStatus.Running ||
                    timestamp > _lastLocationTimestamp;

                _currentLocation.IsUserHeadingUpdated = false;
                _currentLocation.IsLocationUpdated    = false;

                if (!_currentLocation.IsLocationServiceEnabled)
                {
                    yield return(_waitUpdateTime);

                    continue;
                }

                // device orientation, user heading get calculated below
                _deviceOrientationSmoothing.Add(Input.compass.trueHeading);
                _currentLocation.DeviceOrientation = (float)_deviceOrientationSmoothing.Calculate();


                //_currentLocation.LatitudeLongitude = new Vector2d(lastData.latitude, lastData.longitude);
                // HACK to get back to double precision, does this even work?
                // https://forum.unity.com/threads/precision-of-location-longitude-is-worse-when-longitude-is-beyond-100-degrees.133192/#post-1835164
                double   latitude         = double.Parse(lastData.latitude.ToString("R", invariantCulture), invariantCulture);
                double   longitude        = double.Parse(lastData.longitude.ToString("R", invariantCulture), invariantCulture);
                Vector2d previousLocation = new Vector2d(_currentLocation.LatitudeLongitude.x, _currentLocation.LatitudeLongitude.y);
                _currentLocation.LatitudeLongitude = new Vector2d(latitude, longitude);

                _currentLocation.Accuracy = (float)Math.Floor(lastData.horizontalAccuracy);
                // sometimes Unity's timestamp doesn't seem to get updated, or even jump back in time
                // do an additional check if location has changed
                _currentLocation.IsLocationUpdated = timestamp > _lastLocationTimestamp || !_currentLocation.LatitudeLongitude.Equals(previousLocation);
                _currentLocation.Timestamp         = timestamp;
                _lastLocationTimestamp             = timestamp;

                if (_currentLocation.IsLocationUpdated)
                {
                    if (_lastPositions.Count > 0)
                    {
                        // only add position if user has moved +1m since we added the previous position to the list
                        CheapRuler cheapRuler = new CheapRuler(_currentLocation.LatitudeLongitude.x, CheapRulerUnits.Meters);
                        Vector2d   p          = _currentLocation.LatitudeLongitude;
                        double     distance   = cheapRuler.Distance(
                            new double[] { p.y, p.x },
                            new double[] { _lastPositions[0].y, _lastPositions[0].x }
                            );
                        if (distance > 1.0)
                        {
                            _lastPositions.Add(_currentLocation.LatitudeLongitude);
                        }
                    }
                    else
                    {
                        _lastPositions.Add(_currentLocation.LatitudeLongitude);
                    }
                }

                // if we have enough positions calculate user heading ourselves.
                // Unity does not provide bearing based on GPS locations, just
                // device orientation based on Compass.Heading.
                // nevertheless, use compass for intial UserHeading till we have
                // enough values to calculate ourselves.
                if (_lastPositions.Count < _maxLastPositions)
                {
                    _currentLocation.UserHeading          = _currentLocation.DeviceOrientation;
                    _currentLocation.IsUserHeadingUpdated = true;
                }
                else
                {
                    Vector2d   newestPos  = _lastPositions[0];
                    Vector2d   oldestPos  = _lastPositions[_maxLastPositions - 1];
                    CheapRuler cheapRuler = new CheapRuler(newestPos.x, CheapRulerUnits.Meters);
                    // distance between last and first position in our buffer
                    double distance = cheapRuler.Distance(
                        new double[] { newestPos.y, newestPos.x },
                        new double[] { oldestPos.y, oldestPos.x }
                        );
                    // positions are minimum required distance apart (user is moving), calculate user heading
                    if (distance >= _minDistanceOldestNewestPosition)
                    {
                        float[] lastHeadings = new float[_maxLastPositions - 1];

                        for (int i = 1; i < _maxLastPositions; i++)
                        {
                            // atan2 increases angle CCW, flip sign of latDiff to get CW
                            double latDiff = -(_lastPositions[i].x - _lastPositions[i - 1].x);
                            double lngDiff = _lastPositions[i].y - _lastPositions[i - 1].y;
                            // +90.0 to make top (north) 0°
                            double heading = (Math.Atan2(latDiff, lngDiff) * 180.0 / Math.PI) + 90.0f;
                            // stay within [0..360]° range
                            if (heading < 0)
                            {
                                heading += 360;
                            }
                            if (heading >= 360)
                            {
                                heading -= 360;
                            }
                            lastHeadings[i - 1] = (float)heading;
                        }

                        _userHeadingSmoothing.Add(lastHeadings[0]);
                        float finalHeading = (float)_userHeadingSmoothing.Calculate();

                        //fix heading to have 0° for north, 90° for east, 180° for south and 270° for west
                        finalHeading = finalHeading >= 180.0f ? finalHeading - 180.0f : finalHeading + 180.0f;


                        _currentLocation.UserHeading          = finalHeading;
                        _currentLocation.IsUserHeadingUpdated = true;
                    }
                }

                _currentLocation.TimestampDevice = UnixTimestampUtils.To(DateTime.UtcNow);
                SendLocation(_currentLocation);

                yield return(_waitUpdateTime);
            }
        }
示例#25
0
 private void Start()
 {
     UniAndroidPermission.RequestPermission(AndroidPermission.ACCESS_FINE_LOCATION, AccessCamera, AccessCamera);
     Invoke("AccessCamera", 0.5f);
 }