├── .editorconfig
├── .github
├── FUNDING.yml
├── ISSUE_TEMPLATE.md
└── PULL_REQUEST_TEMPLATE.md
├── .gitignore
├── CHANGELOG.md
├── LICENSE
├── README.md
├── appveyor.yml
├── art
└── icon.png
├── build.cake
├── build.ps1
├── build.sh
├── cake.packages.config
├── component
├── Details.md
├── GeolocatorPlugin_128x128.png
├── GeolocatorPlugin_512x512.png
├── GettingStarted.md
├── License.md
└── component.template.yaml
├── docs
├── Architecture.md
├── BackgroundUpdates.md
├── CurrentLocation.md
├── FAQ.md
├── Geocoding.md
├── GettingStarted.md
├── LocationChanges.md
├── README.md
└── _config.yml
├── install-android-sdk.ps1
├── nuget
├── Plugin.nuspec
└── readme.txt
├── samples
├── GeolocatorSample.sln
└── GeolocatorSample
│ ├── GeolocatorSample.Droid
│ ├── Assets
│ │ └── AboutAssets.txt
│ ├── GeolocatorSample.Droid.csproj
│ ├── MainActivity.cs
│ ├── Properties
│ │ ├── AndroidManifest.xml
│ │ └── AssemblyInfo.cs
│ └── Resources
│ │ ├── AboutResources.txt
│ │ ├── Resource.Designer.cs
│ │ ├── drawable-hdpi
│ │ └── icon.png
│ │ ├── drawable-xhdpi
│ │ └── icon.png
│ │ ├── drawable-xxhdpi
│ │ └── icon.png
│ │ ├── drawable
│ │ └── icon.png
│ │ ├── layout
│ │ ├── Tabbar.axml
│ │ └── Toolbar.axml
│ │ ├── values-v21
│ │ └── style.xml
│ │ └── values
│ │ ├── colors.xml
│ │ └── style.xml
│ ├── GeolocatorSample.iOS
│ ├── AppDelegate.cs
│ ├── Entitlements.plist
│ ├── GeolocatorSample.iOS.csproj
│ ├── Info.plist
│ ├── Main.cs
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── Resources
│ │ ├── Default-568h@2x.png
│ │ ├── Default-Portrait.png
│ │ ├── Default-Portrait@2x.png
│ │ ├── Default.png
│ │ ├── Default@2x.png
│ │ ├── Icon-60@2x.png
│ │ ├── Icon-60@3x.png
│ │ ├── Icon-76.png
│ │ ├── Icon-76@2x.png
│ │ ├── Icon-Small-40.png
│ │ ├── Icon-Small-40@2x.png
│ │ ├── Icon-Small-40@3x.png
│ │ ├── Icon-Small.png
│ │ ├── Icon-Small@2x.png
│ │ └── Icon-Small@3x.png
│ ├── iTunesArtwork
│ └── iTunesArtwork@2x
│ └── GeolocatorSample
│ ├── App.cs
│ ├── GeolocatorSample.csproj
│ ├── HomePage.xaml
│ ├── HomePage.xaml.cs
│ └── Utils.cs
└── src
├── Geolocator.Plugin
├── Abstractions
│ ├── ActivityType.shared.cs
│ ├── Address.shared.cs
│ ├── GeolocatorUtils.shared.cs
│ ├── IGeolocator.shared.cs
│ ├── ListenerSettings.shared.cs
│ └── Position.shared.cs
├── Android
│ ├── GeolocationContinuousListener.android.cs
│ ├── GeolocationSingleListener.android.cs
│ ├── GeolocationUtils.android.cs
│ ├── GeolocatorImplementation.android.cs
│ └── ManifestInfo.android.cs
├── Apple
│ ├── GeolocationSingleUpdateDelegate.apple.cs
│ ├── GeolocationUtils.apple.cs
│ └── GeolocatorImplementation.apple.cs
├── CrossGeolocator.shared.cs
├── Geolocator.Plugin.csproj
└── UWP
│ ├── Extensions.uwp.cs
│ ├── GeolocatorImplementation.uwp.cs
│ ├── GeolocatorUtils.uwp.cs
│ └── Timeout.uwp.cs
├── Geolocator.sln
└── Tests
├── GeolocatorTests.Droid
├── Assets
│ └── AboutAssets.txt
├── GeolocatorTests.Droid.csproj
├── GeolocatorTests.Droid.csproj.bak
├── MainActivity.cs
├── MainApplication.cs
├── Properties
│ ├── AndroidManifest.xml
│ └── AssemblyInfo.cs
└── Resources
│ ├── AboutResources.txt
│ ├── Resource.designer.cs
│ ├── drawable-hdpi
│ └── icon.png
│ ├── drawable-xhdpi
│ └── icon.png
│ ├── drawable-xxhdpi
│ └── icon.png
│ └── drawable
│ └── icon.png
├── GeolocatorTests.Mac
├── AppDelegate.cs
├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ ├── AppIcon-128.png
│ │ ├── AppIcon-128@2x.png
│ │ ├── AppIcon-16.png
│ │ ├── AppIcon-16@2x.png
│ │ ├── AppIcon-256.png
│ │ ├── AppIcon-256@2x.png
│ │ ├── AppIcon-32.png
│ │ ├── AppIcon-32@2x.png
│ │ ├── AppIcon-512.png
│ │ ├── AppIcon-512@2x.png
│ │ └── Contents.json
│ └── Contents.json
├── Entitlements.plist
├── GeolocatorTests.Mac.csproj
├── Info.plist
├── Main.cs
├── Main.storyboard
├── ViewController.cs
└── ViewController.designer.cs
├── GeolocatorTests.UWP
├── App.xaml
├── App.xaml.cs
├── Assets
│ ├── LockScreenLogo.scale-200.png
│ ├── SplashScreen.scale-200.png
│ ├── Square150x150Logo.scale-200.png
│ ├── Square44x44Logo.scale-200.png
│ ├── Square44x44Logo.targetsize-24_altform-unplated.png
│ ├── StoreLogo.png
│ └── Wide310x150Logo.scale-200.png
├── GeolocatorTests.UWP.csproj
├── MainPage.xaml
├── MainPage.xaml.cs
├── Package.appxmanifest
└── Properties
│ ├── AssemblyInfo.cs
│ └── Default.rd.xml
├── GeolocatorTests.iOS
├── AppDelegate.cs
├── Entitlements.plist
├── GeolocatorTests.iOS.csproj
├── GeolocatorTests.iOS.csproj.bak
├── Info.plist
├── Main.cs
└── Resources
│ ├── Images.xcassets
│ └── AppIcons.appiconset
│ │ └── Contents.json
│ └── LaunchScreen.xib
├── GeolocatorTests.tvOS
├── AppDelegate.cs
├── Entitlements.plist
├── GeolocatorTests.tvOS.csproj
├── GettingStarted.Xamarin
├── Info.plist
├── Main.cs
├── Main.storyboard
├── Resources
│ └── Assets.xcassets
│ │ └── App Icon & Top Shelf Image.brandassets
│ │ ├── App Icon - Large.imagestack
│ │ ├── Back.imagestacklayer
│ │ │ ├── Content.imageset
│ │ │ │ └── Contents.json
│ │ │ └── Contents.json
│ │ ├── Contents.json
│ │ ├── Front.imagestacklayer
│ │ │ ├── Content.imageset
│ │ │ │ └── Contents.json
│ │ │ └── Contents.json
│ │ └── Middle.imagestacklayer
│ │ │ ├── Content.imageset
│ │ │ └── Contents.json
│ │ │ └── Contents.json
│ │ ├── App Icon - Small.imagestack
│ │ ├── Back.imagestacklayer
│ │ │ ├── Content.imageset
│ │ │ │ └── Contents.json
│ │ │ └── Contents.json
│ │ ├── Contents.json
│ │ ├── Front.imagestacklayer
│ │ │ ├── Content.imageset
│ │ │ │ └── Contents.json
│ │ │ └── Contents.json
│ │ └── Middle.imagestacklayer
│ │ │ ├── Content.imageset
│ │ │ └── Contents.json
│ │ │ └── Contents.json
│ │ ├── Contents.json
│ │ ├── Top Shelf Image Wide.imageset
│ │ └── Contents.json
│ │ └── Top Shelf Image.imageset
│ │ └── Contents.json
├── ViewController.cs
└── ViewController.designer.cs
└── GeolocatorTests
├── App.cs
├── GeolocatorTests.csproj
├── HomePage.xaml
├── HomePage.xaml.cs
└── Utils.cs
/.editorconfig:
--------------------------------------------------------------------------------
1 | # Suppress: EC112
2 | # top-most EditorConfig file
3 | root = true
4 |
5 | # Don't use tabs for indentation.
6 | [*]
7 | indent_style = tab
8 | # (Please don't specify an indent_size here; that has too many unintended consequences.)
9 |
10 | # Code files
11 | [*.{cs,csx,vb,vbx}]
12 | indent_size = 4
13 |
14 | # Xml project files
15 | [*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}]
16 | indent_size = 2
17 |
18 | # Xml config files
19 | [*.{props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct}]
20 | indent_size = 2
21 |
22 | # JSON files
23 | [*.json]
24 | indent_size = 2
25 |
26 | # Dotnet code style settings:
27 | [*.{cs,vb}]
28 | # Sort using and Import directives with System.* appearing first
29 | dotnet_sort_system_directives_first = false
30 | # Avoid "this." and "Me." if not necessary
31 | dotnet_style_qualification_for_field = false:suggestion
32 | dotnet_style_qualification_for_property = false:suggestion
33 | dotnet_style_qualification_for_method = false:suggestion
34 | dotnet_style_qualification_for_event = false:suggestion
35 |
36 | # Use language keywords instead of framework type names for type references
37 | dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
38 | dotnet_style_predefined_type_for_member_access = true:suggestion
39 |
40 | # Suggest more modern language features when available
41 | dotnet_style_object_initializer = true:suggestion
42 | dotnet_style_collection_initializer = true:suggestion
43 | dotnet_style_coalesce_expression = true:suggestion
44 | dotnet_style_null_propagation = true:suggestion
45 | dotnet_style_explicit_tuple_names = true:suggestion
46 |
47 | # Naming Conventions:
48 | # Pascal Casing
49 | dotnet_naming_symbols.method_and_property_symbols.applicable_kinds= method,property,enum
50 | dotnet_naming_symbols.method_and_property_symbols.applicable_accessibilities = *
51 | dotnet_naming_style.pascal_case_style.capitalization = pascal_case
52 |
53 | dotnet_naming_rule.methods_and_properties_must_be_pascal_case.severity = warning
54 | dotnet_naming_rule.methods_and_properties_must_be_pascal_case.symbols = method_and_property_symbols
55 | dotnet_naming_rule.methods_and_properties_must_be_pascal_case.style = pascal_case_style
56 |
57 | # Non-public members must be lower-case
58 | dotnet_naming_symbols.non_public_symbols.applicable_kinds = property,method,field,event,delegate
59 | dotnet_naming_symbols.non_public_symbols.applicable_accessibilities = private
60 | dotnet_naming_style.all_lower_case_style.capitalization = camel_case
61 |
62 | dotnet_naming_rule.non_public_members_must_be_lower_case.severity = warning
63 | dotnet_naming_rule.non_public_members_must_be_lower_case.symbols = non_public_symbols
64 | dotnet_naming_rule.non_public_members_must_be_lower_case.style = all_lower_case_style
65 |
66 | # CSharp code style settings:
67 | [*.cs]
68 | # Do not prefer "var" everywhere
69 | csharp_style_var_for_built_in_types = true:suggestion
70 | csharp_style_var_when_type_is_apparent = true:suggestion
71 | csharp_style_var_elsewhere = true:suggestion
72 |
73 | # Prefer method-like constructs to have a block body
74 | csharp_style_expression_bodied_methods = true:suggestion
75 | csharp_style_expression_bodied_constructors = true:none
76 | csharp_style_expression_bodied_operators = true:none
77 |
78 | # Prefer property-like constructs to have an expression-body
79 | csharp_style_expression_bodied_properties = true:suggestion
80 | csharp_style_expression_bodied_indexers = true:none
81 | csharp_style_expression_bodied_accessors = true:none
82 |
83 | # Suggest more modern language features when available
84 | csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
85 | csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
86 | csharp_style_inlined_variable_declaration = true:suggestion
87 | csharp_style_throw_expression = true:suggestion
88 | csharp_style_conditional_delegate_call = true:suggestion
89 |
90 | # Newline settings
91 | csharp_new_line_before_open_brace = all
92 | csharp_new_line_before_else = true
93 | csharp_new_line_before_catch = true
94 | csharp_new_line_before_finally = true
95 | csharp_new_line_before_members_in_object_initializers = true
96 | csharp_new_line_before_members_in_anonymous_types = true
97 |
98 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: jamesmontemagno
2 | patreon: mergeconflictfm
3 | custom: https://www.buymeacoffee.com/jamesmontemagno
4 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | For common questions and issues see the [FAQ](https://jamesmontemagno.github.io/GeolocatorPlugin/FAQ.html)
2 |
3 | If you are creating an issue for a BUG please fill out this information. If you are asking a question or requesting a feature you can delete the sections below.
4 |
5 | **Failure to fill out this information will result in this issue being closed.** If you post a full stack trace in a bug it will be closed, please post it to http://gist.github.com and then post the link here.
6 |
7 | ## Bug Information
8 |
9 | Version Number of Plugin:
10 | Device Tested On:
11 | Simulator Tested On:
12 | Version of VS:
13 | Version of Xamarin:
14 | Versions of other things you are using:
15 |
16 | ### Steps to reproduce the Behavior
17 |
18 | ### Expected Behavior
19 |
20 | ### Actual Behavior
21 |
22 | ### Code snippet
23 |
24 | ### Screenshotst
25 |
26 |
27 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | Please take a moment to fill out the following:
2 |
3 | Fixes # .
4 |
5 | Changes Proposed in this pull request:
6 | -
7 | -
8 | -
9 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.userosscache
8 | *.sln.docstates
9 |
10 | # User-specific files (MonoDevelop/Xamarin Studio)
11 | *.userprefs
12 |
13 | # Build results
14 | [Dd]ebug/
15 | [Dd]ebugPublic/
16 | [Rr]elease/
17 | [Rr]eleases/
18 | x64/
19 | x86/
20 | bld/
21 | [Bb]in/
22 | [Oo]bj/
23 |
24 | # Visual Studio 2015 cache/options directory
25 | .vs/
26 | # Uncomment if you have tasks that create the project's static files in wwwroot
27 | #wwwroot/
28 |
29 | # MSTest test Results
30 | [Tt]est[Rr]esult*/
31 | [Bb]uild[Ll]og.*
32 |
33 | # NUNIT
34 | *.VisualState.xml
35 | TestResult.xml
36 |
37 | # Build Results of an ATL Project
38 | [Dd]ebugPS/
39 | [Rr]eleasePS/
40 | dlldata.c
41 |
42 | # DNX
43 | project.lock.json
44 | artifacts/
45 |
46 | *_i.c
47 | *_p.c
48 | *_i.h
49 | *.ilk
50 | *.meta
51 | *.obj
52 | *.pch
53 | *.pdb
54 | *.pgc
55 | *.pgd
56 | *.rsp
57 | *.sbr
58 | *.tlb
59 | *.tli
60 | *.tlh
61 | *.tmp
62 | *.tmp_proj
63 | *.log
64 | *.vspscc
65 | *.vssscc
66 | .builds
67 | *.pidb
68 | *.svclog
69 | *.scc
70 |
71 | # Chutzpah Test files
72 | _Chutzpah*
73 |
74 | # Visual C++ cache files
75 | ipch/
76 | *.aps
77 | *.ncb
78 | *.opendb
79 | *.opensdf
80 | *.sdf
81 | *.cachefile
82 |
83 | # Visual Studio profiler
84 | *.psess
85 | *.vsp
86 | *.vspx
87 | *.sap
88 |
89 | # TFS 2012 Local Workspace
90 | $tf/
91 |
92 | # Guidance Automation Toolkit
93 | *.gpState
94 |
95 | # ReSharper is a .NET coding add-in
96 | _ReSharper*/
97 | *.[Rr]e[Ss]harper
98 | *.DotSettings.user
99 |
100 | # JustCode is a .NET coding add-in
101 | .JustCode
102 |
103 | # TeamCity is a build add-in
104 | _TeamCity*
105 |
106 | # DotCover is a Code Coverage Tool
107 | *.dotCover
108 |
109 | # NCrunch
110 | _NCrunch_*
111 | .*crunch*.local.xml
112 | nCrunchTemp_*
113 |
114 | # MightyMoose
115 | *.mm.*
116 | AutoTest.Net/
117 |
118 | # Web workbench (sass)
119 | .sass-cache/
120 |
121 | # Installshield output folder
122 | [Ee]xpress/
123 |
124 | # DocProject is a documentation generator add-in
125 | DocProject/buildhelp/
126 | DocProject/Help/*.HxT
127 | DocProject/Help/*.HxC
128 | DocProject/Help/*.hhc
129 | DocProject/Help/*.hhk
130 | DocProject/Help/*.hhp
131 | DocProject/Help/Html2
132 | DocProject/Help/html
133 |
134 | # Click-Once directory
135 | publish/
136 |
137 | # Publish Web Output
138 | *.[Pp]ublish.xml
139 | *.azurePubxml
140 | # TODO: Comment the next line if you want to checkin your web deploy settings
141 | # but database connection strings (with potential passwords) will be unencrypted
142 | *.pubxml
143 | *.publishproj
144 |
145 | # NuGet Packages
146 | *.nupkg
147 | # The packages folder can be ignored because of Package Restore
148 | **/packages/*
149 | # except build/, which is used as an MSBuild target.
150 | !**/packages/build/
151 | # Uncomment if necessary however generally it will be regenerated when needed
152 | #!**/packages/repositories.config
153 | # NuGet v3's project.json files produces more ignoreable files
154 | *.nuget.props
155 | *.nuget.targets
156 |
157 | # Microsoft Azure Build Output
158 | csx/
159 | *.build.csdef
160 |
161 | # Microsoft Azure Emulator
162 | ecf/
163 | rcf/
164 |
165 | # Microsoft Azure ApplicationInsights config file
166 | ApplicationInsights.config
167 |
168 | # Windows Store app package directory
169 | AppPackages/
170 | BundleArtifacts/
171 |
172 | # Visual Studio cache files
173 | # files ending in .cache can be ignored
174 | *.[Cc]ache
175 | # but keep track of directories ending in .cache
176 | !*.[Cc]ache/
177 |
178 | # Others
179 | ClientBin/
180 | ~$*
181 | *~
182 | *.dbmdl
183 | *.dbproj.schemaview
184 | *.pfx
185 | *.publishsettings
186 | node_modules/
187 | orleans.codegen.cs
188 |
189 | # RIA/Silverlight projects
190 | Generated_Code/
191 |
192 | # Backup & report files from converting an old project file
193 | # to a newer Visual Studio version. Backup files are not needed,
194 | # because we have git ;-)
195 | _UpgradeReport_Files/
196 | Backup*/
197 | UpgradeLog*.XML
198 | UpgradeLog*.htm
199 |
200 | # SQL Server files
201 | *.mdf
202 | *.ldf
203 |
204 | # Business Intelligence projects
205 | *.rdl.data
206 | *.bim.layout
207 | *.bim_*.settings
208 |
209 | # Microsoft Fakes
210 | FakesAssemblies/
211 |
212 | # GhostDoc plugin setting file
213 | *.GhostDoc.xml
214 |
215 | # Node.js Tools for Visual Studio
216 | .ntvs_analysis.dat
217 |
218 | # Visual Studio 6 build log
219 | *.plg
220 |
221 | # Visual Studio 6 workspace options file
222 | *.opt
223 |
224 | # Visual Studio LightSwitch build output
225 | **/*.HTMLClient/GeneratedArtifacts
226 | **/*.DesktopClient/GeneratedArtifacts
227 | **/*.DesktopClient/ModelManifest.xml
228 | **/*.Server/GeneratedArtifacts
229 | **/*.Server/ModelManifest.xml
230 | _Pvt_Extensions
231 |
232 | # Paket dependency manager
233 | .paket/paket.exe
234 |
235 | # FAKE - F# Make
236 | .fake/
237 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## Changelog
2 |
3 | ### 4.2.0
4 | * Bump permissions plugin and other nugets
5 |
6 | ### 4.1.3
7 | * Android: Add ProvidersToUseWhileListening and ProvidersToUse Helpers to limit providers used.
8 |
9 | ### 4.1.2
10 | * Optimize iOS permission handling for iOS 11
11 |
12 | ### 4.1.0
13 | * All: Add Geocoding of Address to Position Coordinates
14 | * Add Admin/SubAdmin area to Address
15 | * Add Distance Utilities into Abstractions
16 | * Android/iOS Enhance permissions support
17 | * Android: Add ability to filter out providers
18 |
19 |
20 |
21 | ### 4.0.1
22 | Breaking Changes:
23 | * Parameters have all been updated on several methods
24 | * Remove Windows Phone 8/8.1 and Windows Store 8.1
25 | * Now .NET Standard Library
26 |
27 | New Features:
28 | * Added iOS Support for Significant Changes & Deferral
29 | * Added GetLastKnownLocation - Returns faster if cached
30 | * Added GetAddressedForPosition - Retuns an address based on location passed in
31 |
32 |
33 | Bug Fixes & Enhancements:
34 | * Android Improved when GPS is available or not
35 | * Better handling of timeouts
36 | * Lots of small little updates and changes
37 |
38 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 James Montemagno
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## Geolocator Plugin for Xamarin and Windows
2 |
3 | Simple cross platform plugin to get GPS location including heading, speed, and more. Additionally, you can track geolocation changes, reverse geocode, and more.
4 |
5 | ## Documentation
6 | Get started by reading through the [Geolocator Plugin documentation](https://jamesmontemagno.github.io/GeolocatorPlugin/).
7 |
8 | For common questions and issues see the [FAQ](https://jamesmontemagno.github.io/GeolocatorPlugin/FAQ.html)
9 |
10 | ## NuGet
11 | * Available on NuGet: [Xam.Plugin.Geolocator](http://www.nuget.org/packages/Xam.Plugin.Geolocator) [](https://www.nuget.org/packages/Xam.Plugin.Geolocator/)
12 |
13 | ### The Future: [Xamarin.Essentials](https://docs.microsoft.com/xamarin/essentials/index?WT.mc_id=friends-0000-jamont)
14 |
15 | I have been working on Plugins for Xamarin for a long time now. Through the years I have always wanted to create a single, optimized, and official package from the Xamarin team at Microsoft that could easily be consumed by any application. The time is now with [Xamarin.Essentials](https://docs.microsoft.com/xamarin/essentials/index?WT.mc_id=friends-0000-jamont), which offers over 50 cross-platform native APIs in a single optimized package. I worked on this new library with an amazing team of developers and I highly highly highly recommend you check it out.
16 |
17 | I will continue to work and maintain my Plugins, but I do recommend you checkout Xamarin.Essentials to see if it is a great fit your app as it has been for all of mine!
18 |
19 | ### Build
20 | * [](https://ci.appveyor.com/project/JamesMontemagno/geolocatorplugin)
21 | * CI NuGet Feed: https://ci.appveyor.com/nuget/geolocatorplugin
22 |
23 | **Platform Support**
24 |
25 | Version 4.X
26 |
27 | |Platform|Version|
28 | | ------------------- | :------------------: |
29 | |Xamarin.iOS|iOS 8+|
30 | |Xamarin.Android|API 14+|
31 | |Windows 10 UWP|10+|
32 | |macOS|All|
33 | |tvOS|10+|
34 |
35 | **Feature requests**
36 | Vote for a feature requests at
37 | https://github.com/jamesmontemagno/GeolocatorPlugin/labels/feature
38 |
39 | ### Created By: [@JamesMontemagno](http://twitter.com/jamesmontemagno)
40 | * Twitter: [@JamesMontemagno](http://twitter.com/jamesmontemagno)
41 | * Blog: [MotzCod.es](http://motzcod.es), [Micro Blog](http://motz.micro.blog)
42 | * Podcasts: [Merge Conflict](http://mergeconflict.fm), [Coffeehouse Blunders](http://blunders.fm), [The Xamarin Podcast](http://xamarinpodcast.com)
43 | * Video: [The Xamarin Show on Channel 9](http://xamarinshow.com), [YouTube Channel](https://www.youtube.com/jamesmontemagno)
44 |
45 | #### License
46 | The MIT License (MIT) see [License file](LICENSE)
47 |
48 | This is a derivative to [Xamarin.Mobile's Geolocator](http://github.com/xamarin/xamarin.mobile) with a cross platform API and other enhancements.
49 |
50 | ### Want To Support This Project?
51 | All I have ever asked is to be active by submitting bugs, features, and sending those pull requests down! Want to go further? Make sure to subscribe to my weekly development podcast [Merge Conflict](http://mergeconflict.fm), where I talk all about awesome Xamarin goodies and you can optionally support the show by becoming a [supporter on Patreon](https://www.patreon.com/mergeconflictfm).
52 |
--------------------------------------------------------------------------------
/appveyor.yml:
--------------------------------------------------------------------------------
1 | version: 4.2.0.{build}-beta
2 | image: Visual Studio 2017
3 | configuration: Release
4 | environment:
5 | CAKE_SETTINGS_SKIPVERIFICATION: true
6 | ANDROID_HOME: 'C:\Program Files (x86)\Android\android-sdk\'
7 | assembly_info:
8 | patch: true
9 | file: '**\AssemblyInfo.*'
10 | assembly_version: '{version}'
11 | assembly_file_version: '{version}'
12 | assembly_informational_version: '{version}'
13 | build_script:
14 | - cmd: >-
15 | powershell .\build.ps1 -Target Default -Verbosity diagnostic
16 | artifacts:
17 | - path: ./Build/nuget/*.nupkg
18 | name: NuGet
19 |
--------------------------------------------------------------------------------
/art/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jamesmontemagno/GeolocatorPlugin/f0b80019c9f127d03341bb6e191dbf58ac262580/art/icon.png
--------------------------------------------------------------------------------
/build.cake:
--------------------------------------------------------------------------------
1 | #addin nuget:?package=Cake.Android.SdkManager
2 |
3 | var TARGET = Argument ("target", Argument ("t", "Default"));
4 | var VERSION = EnvironmentVariable ("APPVEYOR_BUILD_VERSION") ?? Argument("version", "0.0.9999");
5 | var CONFIG = Argument("configuration", EnvironmentVariable ("CONFIGURATION") ?? "Release");
6 | var SLN = "./src/Geolocator.sln";
7 |
8 | var ANDROID_HOME = EnvironmentVariable ("ANDROID_HOME") ?? Argument ("android_home", "");
9 |
10 | Task("Libraries").Does(()=>
11 | {
12 | NuGetRestore (SLN);
13 | MSBuild (SLN, c => {
14 | c.Configuration = CONFIG;
15 | c.MSBuildPlatform = Cake.Common.Tools.MSBuild.MSBuildPlatform.x86;
16 | });
17 | });
18 |
19 | Task ("NuGet")
20 | .IsDependentOn ("AndroidSDK")
21 | .IsDependentOn ("Libraries")
22 | .Does (() =>
23 | {
24 | if(!DirectoryExists("./Build/nuget/"))
25 | CreateDirectory("./Build/nuget");
26 |
27 | NuGetPack ("./nuget/Plugin.nuspec", new NuGetPackSettings {
28 | Version = VERSION,
29 | OutputDirectory = "./Build/nuget/",
30 | BasePath = "./"
31 | });
32 | });
33 |
34 | Task ("AndroidSDK")
35 | .Does (() =>
36 | {
37 | Information ("ANDROID_HOME: {0}", ANDROID_HOME);
38 |
39 | var androidSdkSettings = new AndroidSdkManagerToolSettings {
40 | SdkRoot = ANDROID_HOME,
41 | SkipVersionCheck = true
42 | };
43 |
44 | try { AcceptLicenses (androidSdkSettings); } catch { }
45 |
46 | AndroidSdkManagerInstall (new [] {
47 | "platforms;android-15",
48 | "platforms;android-23",
49 | "platforms;android-25",
50 | "platforms;android-26"
51 | }, androidSdkSettings);
52 | });
53 |
54 | //Build the component, which build samples, nugets, and libraries
55 | Task ("Default").IsDependentOn("NuGet");
56 |
57 | Task ("Clean").Does (() =>
58 | {
59 | CleanDirectory ("./component/tools/");
60 | CleanDirectories ("./Build/");
61 | CleanDirectories ("./**/bin");
62 | CleanDirectories ("./**/obj");
63 | });
64 |
65 | RunTarget (TARGET);
66 |
--------------------------------------------------------------------------------
/build.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##########################################################################
4 | # This is the Cake bootstrapper script for Linux and OS X.
5 | # This file was downloaded from https://github.com/cake-build/resources
6 | # Feel free to change this file to fit your needs.
7 | ##########################################################################
8 |
9 | # Define directories.
10 | SCRIPT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
11 | TOOLS_DIR=$SCRIPT_DIR/tools
12 | NUGET_EXE=$TOOLS_DIR/nuget.exe
13 | CAKE_EXE=$TOOLS_DIR/Cake/Cake.exe
14 | PACKAGES_CONFIG=$TOOLS_DIR/packages.config
15 | PACKAGES_CONFIG_MD5=$TOOLS_DIR/packages.config.md5sum
16 |
17 | # Define md5sum or md5 depending on Linux/OSX
18 | MD5_EXE=
19 | if [[ "$(uname -s)" == "Darwin" ]]; then
20 | MD5_EXE="md5 -r"
21 | else
22 | MD5_EXE="md5sum"
23 | fi
24 |
25 | # Define default arguments.
26 | SCRIPT="build.cake"
27 | TARGET="Default"
28 | CONFIGURATION="Release"
29 | VERBOSITY="verbose"
30 | DRYRUN=
31 | SHOW_VERSION=false
32 | SCRIPT_ARGUMENTS=()
33 |
34 | # Parse arguments.
35 | for i in "$@"; do
36 | case $1 in
37 | -s|--script) SCRIPT="$2"; shift ;;
38 | -t|--target) TARGET="$2"; shift ;;
39 | -c|--configuration) CONFIGURATION="$2"; shift ;;
40 | -v|--verbosity) VERBOSITY="$2"; shift ;;
41 | -d|--dryrun) DRYRUN="-dryrun" ;;
42 | --version) SHOW_VERSION=true ;;
43 | --) shift; SCRIPT_ARGUMENTS+=("$@"); break ;;
44 | *) SCRIPT_ARGUMENTS+=("$1") ;;
45 | esac
46 | shift
47 | done
48 |
49 | # Make sure the tools folder exist.
50 | if [ ! -d "$TOOLS_DIR" ]; then
51 | mkdir "$TOOLS_DIR"
52 | fi
53 |
54 | # Make sure that packages.config exist.
55 | if [ ! -f "$TOOLS_DIR/packages.config" ]; then
56 | echo "Downloading packages.config..."
57 | curl -Lsfo "$TOOLS_DIR/packages.config" http://cakebuild.net/download/bootstrapper/packages
58 | if [ $? -ne 0 ]; then
59 | echo "An error occured while downloading packages.config."
60 | exit 1
61 | fi
62 | fi
63 |
64 | # Download NuGet if it does not exist.
65 | if [ ! -f "$NUGET_EXE" ]; then
66 | echo "Downloading NuGet..."
67 | curl -Lsfo "$NUGET_EXE" https://dist.nuget.org/win-x86-commandline/latest/nuget.exe
68 | if [ $? -ne 0 ]; then
69 | echo "An error occured while downloading nuget.exe."
70 | exit 1
71 | fi
72 | fi
73 |
74 | # Restore tools from NuGet.
75 | pushd "$TOOLS_DIR" >/dev/null
76 | if [ ! -f $PACKAGES_CONFIG_MD5 ] || [ "$( cat $PACKAGES_CONFIG_MD5 | sed 's/\r$//' )" != "$( $MD5_EXE $PACKAGES_CONFIG | awk '{ print $1 }' )" ]; then
77 | find . -type d ! -name . | xargs rm -rf
78 | fi
79 |
80 | mono "$NUGET_EXE" install -ExcludeVersion
81 | if [ $? -ne 0 ]; then
82 | echo "Could not restore NuGet packages."
83 | exit 1
84 | fi
85 |
86 | $MD5_EXE $PACKAGES_CONFIG | awk '{ print $1 }' >| $PACKAGES_CONFIG_MD5
87 |
88 | popd >/dev/null
89 |
90 | # Make sure that Cake has been installed.
91 | if [ ! -f "$CAKE_EXE" ]; then
92 | echo "Could not find Cake.exe at '$CAKE_EXE'."
93 | exit 1
94 | fi
95 |
96 | # Start Cake
97 | if $SHOW_VERSION; then
98 | exec mono "$CAKE_EXE" -version
99 | else
100 | exec mono "$CAKE_EXE" $SCRIPT -verbosity=$VERBOSITY -configuration=$CONFIGURATION -target=$TARGET $DRYRUN "${SCRIPT_ARGUMENTS[@]}"
101 | fi
--------------------------------------------------------------------------------
/cake.packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/component/Details.md:
--------------------------------------------------------------------------------
1 | # Geolocator Plugin details
2 |
3 | Simple cross platform plugin to get GPS location including heading, speed, and more.
4 |
5 | #### Features
6 | * Async GPS Location Detection
7 | * Heading
8 | * Speed
9 | * Listen for Changes
10 |
11 |
12 | Works from any shared code or PCL project.
13 |
14 | Find more plugins at: http://www.github.com/xamarin/plugins
--------------------------------------------------------------------------------
/component/GeolocatorPlugin_128x128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jamesmontemagno/GeolocatorPlugin/f0b80019c9f127d03341bb6e191dbf58ac262580/component/GeolocatorPlugin_128x128.png
--------------------------------------------------------------------------------
/component/GeolocatorPlugin_512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jamesmontemagno/GeolocatorPlugin/f0b80019c9f127d03341bb6e191dbf58ac262580/component/GeolocatorPlugin_512x512.png
--------------------------------------------------------------------------------
/component/GettingStarted.md:
--------------------------------------------------------------------------------
1 | # Getting Started with Geolocator Plugin
2 |
3 | ### API Usage
4 |
5 | Call **CrossGeolocator.Current** from any project or PCL to gain access to APIs.
6 |
7 | ```
8 | var locator = CrossGeolocator.Current;
9 | locator.DesiredAccuracy = 50;
10 |
11 | var position = await locator.GetPositionAsync (timeoutMilliseconds: 10000);
12 |
13 | Console.WriteLine ("Position Status: {0}", position.Timestamp);
14 | Console.WriteLine ("Position Latitude: {0}", position.Latitude);
15 | Console.WriteLine ("Position Longitude: {0}", position.Longitude);
16 | ```
17 |
18 | ### **IMPORTANT**
19 | Android:
20 |
21 | You must request ACCESS_COARSE_LOCATION & ACCESS_FINE_LOCATION permission
22 |
23 | iOS:
24 |
25 | In iOS 8 you now have to call either RequestWhenInUseAuthorization or RequestAlwaysAuthorization on the location manager. Additionally you need to add either the concisely named NSLocationWhenInUseUsageDescription or NSLocationAlwaysUsageDescription to your Info.plist.
26 | See: http://motzcod.es/post/97662738237/scanning-for-ibeacons-in-ios-8
27 |
28 | Windows Phone:
29 |
30 | You must set the ID_CAP_LOCATION permission.
--------------------------------------------------------------------------------
/component/License.md:
--------------------------------------------------------------------------------
1 | # Geolocator Plugin license
2 |
3 |
4 | The MIT License (MIT)
5 |
6 | Copyright (c) 2014 James Montemagno / Refractored LLC
7 |
8 | Permission is hereby granted, free of charge, to any person obtaining a copy of
9 | this software and associated documentation files (the "Software"), to deal in
10 | the Software without restriction, including without limitation the rights to
11 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
12 | the Software, and to permit persons to whom the Software is furnished to do so,
13 | subject to the following conditions:
14 |
15 | The above copyright notice and this permission notice shall be included in all
16 | copies or substantial portions of the Software.
17 |
18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
20 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
21 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
22 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/component/component.template.yaml:
--------------------------------------------------------------------------------
1 | %YAML 1.2
2 | ---
3 | version: {VERSION}
4 | name: Geolocator Plugin
5 | id: GeolocatorPlugin
6 | publisher: James Montemagno
7 | license: License.md
8 | skip_docs: true
9 | icons:
10 | - GeolocatorPlugin_128x128.png
11 | - GeolocatorPlugin_512x512.png
12 | publisher-url: http://www.github.com/jamesmontemagno/GeolocatorPlugin
13 | is_shell: true
14 | packages:
15 | ios: Xam.Plugin.Geolocator, Version={VERSION}
16 | ios-unified: Xam.Plugin.Geolocator, Version={VERSION}
17 | android: Xam.Plugin.Geolocator, Version={VERSION}
18 | winphone-8.0: Xam.Plugin.Geolocator, Version={VERSION}
19 | winphone-8.1: Xam.Plugin.Geolocator, Version={VERSION}
20 | winuniversal-10.0: Xam.Plugin.Geolocator, Version={VERSION}
21 | summary: Easily access the geolocation features of any device.
22 | details: Details.md
23 | getting-started: GettingStarted.md
24 | samples:
25 | - name: Geolocator Samples (iOS, Android, and Windows)
26 | path: "../samples/GeolocatorSample.sln"
27 | removeProjects:
28 | - Geolocator.Plugin
29 | - Geolocator.Plugin.Abstractions
30 | - Geolocator.Plugin.Android
31 | - Geolocator.Plugin.iOSUnified
32 | - Geolocator.Plugin.WinPhone
33 | installNuGets:
34 | - project: GeolocatorSample
35 | packages:
36 | - Xam.Plugin.Geolocator
37 | - project: GeolocatorSample.iOS
38 | packages:
39 | - Xam.Plugin.Geolocator
40 | - project: GeolocatorSample.Droid
41 | packages:
42 | - Xam.Plugin.Geolocator
43 | - project: GeolocatorSample.WinPhone
44 | packages:
45 | - Xam.Plugin.Geolocator
46 | no_build: true
47 | skip_docs: true
48 | local-nuget-repo: ../Build/nuget
49 | no_build: true
50 | ...
51 |
--------------------------------------------------------------------------------
/docs/Architecture.md:
--------------------------------------------------------------------------------
1 |
2 | ## Architecture
3 |
4 | I get a lot of questions about architecture and how to unit tests plugins. So here are some things to be aware of for any plugin that I publish.
5 |
6 | ### What's with this .Current Global Variable? Why can't I use $FAVORITE_IOC_LIBARY
7 | You totally can! Every plugin I create is based on an interface. The static singleton just gives you a super simple way of gaining access to the platform implementation. Realize that the implementation of the plugin lives in your iOS, Android, Windows, etc. Thies means you will need to register it there by instantiating a `Cross___Implementation` from the platform specific projects.
8 |
9 | If you are using a ViewModel/IOC approach your code may look like:
10 |
11 | ```csharp
12 | public MyViewModel()
13 | {
14 | readonly IPLUGIN plugin;
15 | public MyViewModel(IPLUGIN plugin)
16 | {
17 | this.plugin = plugin;
18 | }
19 | }
20 | ```
21 |
22 | ### What About Unit Testing?
23 | To learn about unit testing strategies be sure to read my blog: [Unit Testing Plugins for Xamarin](http://motzcod.es/post/159267241302/unit-testing-plugins-for-xamarin)
24 |
25 |
26 | <= Back to [Table of Contents](README.md)
--------------------------------------------------------------------------------
/docs/BackgroundUpdates.md:
--------------------------------------------------------------------------------
1 | ## Background Updates
2 | Background updates are handled a bit different on each platform. The [My Driving application](https://github.com/azure-samples/mydriving) is a great sample showing how to handle this on all mobile platforms.
3 |
4 | ### iOS
5 | We are lucky here as iOS has background tracking built into the API. iOS is a little bit different as when the user force closes your app everything is gone as there are no background services. This is where the `ListenerSettings` come into play when executing the `StartListeningAsync` method.
6 |
7 | For background notifications you must set background updates in your info.plist under `UIBackgroundModes`.
8 |
9 | In addition to allowing background updates there are a plethora of other options:
10 |
11 | ```csharp
12 | ///
13 | /// Settings for location listening (only applies to iOS). All defaults are set as indicated in the docs for CLLocationManager.
14 | ///
15 | public class ListenerSettings
16 | {
17 | ///
18 | /// Gets or sets whether background location updates should be allowed (>= iOS 9). Default: false
19 | ///
20 | public bool AllowBackgroundUpdates { get; set; } = false;
21 |
22 | ///
23 | /// Gets or sets whether location updates should be paused automatically when the location is unlikely to change (>= iOS 6). Default: true
24 | ///
25 | public bool PauseLocationUpdatesAutomatically { get; set; } = true;
26 |
27 | ///
28 | /// Gets or sets the activity type that should be used to determine when to automatically pause location updates (>= iOS 6). Default: ActivityType.Other
29 | ///
30 | public ActivityType ActivityType { get; set; } = ActivityType.Other;
31 |
32 | ///
33 | /// Gets or sets whether the location manager should only listen for significant changes in location, rather than continuous listening (>= iOS 4). Default: false
34 | ///
35 | public bool ListenForSignificantChanges { get; set; } = false;
36 |
37 | ///
38 | /// Gets or sets whether the location manager should defer location updates until an energy efficient time arrives, or distance and time criteria are met (>= iOS 6). Default: false
39 | ///
40 | public bool DeferLocationUpdates { get; set; } = false;
41 |
42 | ///
43 | /// If deferring location updates, the minimum distance to travel before updates are delivered (>= iOS 6). Set to null for indefinite wait. Default: 500
44 | ///
45 | public double? DeferralDistanceMeters { get; set; } = 500;
46 |
47 | ///
48 | /// If deferring location updates, the minimum time that should elapse before updates are delivered (>= iOS 6). Set to null for indefinite wait. Default: 5 minutes
49 | ///
50 | /// The time between updates (default: 5 minutes).
51 | public TimeSpan? DeferralTime { get; set; } = TimeSpan.FromMinutes(5);
52 | }
53 | ```
54 |
55 | Example:
56 | ```csharp
57 | async Task StartListening()
58 | {
59 | if(CrossGeolocator.Current.IsListening)
60 | return;
61 |
62 | ///This logic will run on the background automatically on iOS, however for Android and UWP you must put logic in background services. Else if your app is killed the location updates will be killed.
63 | await CrossGeolocator.Current.StartListeningAsync(TimeSpan.FromSeconds(5), 10, true, new Plugin.Geolocator.Abstractions.ListenerSettings
64 | {
65 | ActivityType = Plugin.Geolocator.Abstractions.ActivityType.AutomotiveNavigation,
66 | AllowBackgroundUpdates = true,
67 | DeferLocationUpdates = true,
68 | DeferralDistanceMeters = 1,
69 | DeferralTime = TimeSpan.FromSeconds(1),
70 | ListenForSignificantChanges = true,
71 | PauseLocationUpdatesAutomatically = false
72 | });
73 |
74 | CrossGeolocator.Current.PositionChanged += Current_PositionChanged;
75 | }
76 | ```
77 |
78 | ### Android
79 | For this you will want to integrate a foreground service that subscribes to location changes and the user interface binds to. Please read through the [Xamarin.Android Services documentation](https://developer.xamarin.com/guides/android/application_fundamentals/services/)
80 |
81 | ### UWP
82 | There are several different approaches you can take here, but it is recommended to implement [Extended Execution](https://docs.microsoft.com/en-us/windows/uwp/launch-resume/run-minimized-with-extended-execution) for background tracking.
83 |
84 |
85 | <= Back to [Table of Contents](README.md)
--------------------------------------------------------------------------------
/docs/CurrentLocation.md:
--------------------------------------------------------------------------------
1 | ## Checking Current Location
2 | There are a few properties that can be used to easily check connection information using the plugin.
3 |
4 | ### Location Properties
5 | There are several properties on `CrossGeolocator.Current` that can help when getting geolocation and ensuring the hardware has support for geolocation.
6 |
7 | ```csharp
8 | ///
9 | /// Desired accuracy in meters
10 | ///
11 | double DesiredAccuracy { get; set; }
12 | ```
13 | This property tells the location managers that it is okay to be X meters off. The default is 100 meters.
14 |
15 | ```csharp
16 | ///
17 | /// Gets if device supports heading
18 | ///
19 | bool SupportsHeading { get; }
20 | ```
21 | Determines if the device and OS supports returning the heading of the location.
22 |
23 | ```csharp
24 | ///
25 | /// Gets if geolocation is available on device
26 | ///
27 | bool IsGeolocationAvailable { get; }
28 | ```
29 | Determines if geolocation is actually available and capable of getting geolocation.
30 |
31 | ```csharp
32 | ///
33 | /// Gets if geolocation is enabled on device
34 | ///
35 | bool IsGeolocationEnabled { get; }
36 | ```
37 | If the geolocation mechanisms of the device are actually enabled.
38 |
39 | ### Cached/Last Known Location
40 | Before quering for a full location which will boot up sensors for geolocation you can query for the last known or cached location of the manager. It will return `null` if no cached location is available.
41 |
42 | ```csharp
43 | ///
44 | /// Gets the last known and most accurate location.
45 | /// This is usually cached and best to display first before querying for full position.
46 | ///
47 | /// Best and most recent location or null if none found
48 | Task GetLastKnownLocationAsync();
49 | ```
50 |
51 | ### Query Current Location
52 | Requests a query of the current location. This will start the location sensors on the device to attempt to get the current location. It is very possible that the request take much longer or not available, so exception handling should be considered.
53 |
54 | ```csharp
55 | ///
56 | /// Gets position async with specified parameters
57 | ///
58 | /// Timeout to wait, Default Infinite
59 | /// Cancellation token
60 | /// If you would like to include heading
61 | /// Position
62 | Task GetPositionAsync(TimeSpan? timeout = null, CancellationToken? token = null, bool includeHeading = false);
63 | ```
64 |
65 | Full Example:
66 | ```csharp
67 | public async Task GetCurrentLocation()
68 | {
69 | public static async Task GetCurrentPosition()
70 | {
71 | Position position = null;
72 | try
73 | {
74 | var locator = CrossGeolocator.Current;
75 | locator.DesiredAccuracy = 100;
76 |
77 | position = await locator.GetLastKnownLocationAsync();
78 |
79 | if (position != null)
80 | {
81 | //got a cahched position, so let's use it.
82 | return position;
83 | }
84 |
85 | if (!locator.IsGeolocationAvailable || !locator.IsGeolocationEnabled)
86 | {
87 | //not available or enabled
88 | return null;
89 | }
90 |
91 | position = await locator.GetPositionAsync(TimeSpan.FromSeconds(20), null, true);
92 |
93 | }
94 | catch (Exception ex)
95 | {
96 | Debug.WriteLine("Unable to get location: " + ex);
97 | }
98 |
99 | if (position == null)
100 | return null;
101 |
102 | var output = string.Format("Time: {0} \nLat: {1} \nLong: {2} \nAltitude: {3} \nAltitude Accuracy: {4} \nAccuracy: {5} \nHeading: {6} \nSpeed: {7}",
103 | position.Timestamp, position.Latitude, position.Longitude,
104 | position.Altitude, position.AltitudeAccuracy, position.Accuracy, position.Heading, position.Speed);
105 |
106 | Debug.WriteLine(output);
107 |
108 | return position;
109 | }
110 | }
111 | ```
112 |
113 |
114 |
115 | <= Back to [Table of Contents](README.md)
116 |
117 |
--------------------------------------------------------------------------------
/docs/FAQ.md:
--------------------------------------------------------------------------------
1 |
2 | ## FAQ and Common Issues
3 |
4 | Here is a quick guide to questions asked.
5 |
6 | ### I am receiving a "Task was cancelled issue" exception
7 | This is completely possible if the device doesn't return the location in the specified time. It is good to check the cached location first before polling. If you are on an emulator it is very common to get this. You must bring up the emulators settings and push a location to a device. The same can be true for the iOS Simulator.
8 |
9 | ### Does the Android power setting effect geolocation?
10 | Yes, according to the [documentation](https://developer.android.com/about/versions/oreo/background-location-limits.html) If your app is running in the background, the location system service computes a new location for your app only a few times each hour. This is the case even when your app is requesting more frequent location updates.
11 |
12 | ### IsGeolocationAvailable and IsGeolocationEnabled returns false on Android when no permission is granted
13 | This is the current expected behavior, it is the only way to actually query the providers for gps. I recommend that the app developer checks the permissions first using the [Permissions Plugin](https://github.com/jamesmontemagno/PermissionsPlugin).
14 |
15 |
16 | <= Back to [Table of Contents](README.md)
--------------------------------------------------------------------------------
/docs/Geocoding.md:
--------------------------------------------------------------------------------
1 | ## Geocoding
2 |
3 | The geolocator plugin also features common functions when dealing with locations such as Geocoding.
4 |
5 | #### Reverse Geoloding
6 | Based on a location that is passed in attempt to get a list of addresses.
7 |
8 | ```csharp
9 | ///
10 | /// Retrieve addresses for position.
11 | ///
12 | /// Desired position (latitude and longitude)
13 | /// Map Key required only on UWP
14 | /// Addresses of the desired position
15 | Task> GetAddressesForPositionAsync(Position position, string mapKey = null);
16 | ```
17 |
18 | Example:
19 | ```csharp
20 | try
21 | {
22 | string mapKey = null; //only needed on UWP
23 | var addresses = await locator.GetAddressesForPositionAsync (position, mapKey);
24 | var address = addresses.FirstOrDefault();
25 |
26 | if(address == null)
27 | Console.WriteLine ("No address found for position.");
28 | else
29 | Console.WriteLine ("Addresss: {0} {1} {2}", address.Thoroughfare, address.Locality, address.CountryCode);
30 | }
31 | catch(Exception ex)
32 | {
33 | Debug.WriteLine("Unable to get address: " + ex);
34 | }
35 | ```
36 | ### UWP Additional Setup
37 | UWP requires a Bing Map Key, which you can aquire by reading this [piece of documentation](https://docs.microsoft.com/en-us/windows/uwp/maps-and-location/authentication-key) and then pass it in via the `mapKey` property.
38 |
39 |
40 | <= Back to [Table of Contents](README.md)
41 |
--------------------------------------------------------------------------------
/docs/LocationChanges.md:
--------------------------------------------------------------------------------
1 | ## Location Changes
2 | In addition to a one shot location query you can easily register for location changes. By default these are for foreground changes when your application is open. For background or when app is closed be srue to read through the [Background Updates](BackgroundUpdates.md) documentation.
3 |
4 |
5 | ### Start Listening
6 | Before subscribing to events you must start listening, which will start the managers to query for location changes.
7 |
8 | To check to see if you are listning there is a nifty `IsListening` property on the `CrossGeolocator.Current` that you can use.
9 |
10 | ```csharp
11 | ///
12 | /// Gets if you are listening for location changes
13 | ///
14 | bool IsListening { get; }
15 | ```
16 |
17 | Once you are ready to start listening for changes you can call the `StartListeningAsync`. After this, you can add event handlers to get the changes.
18 | ```csharp
19 | ///
20 | /// Start listening for changes
21 | ///
22 | /// Minimum time between updates
23 | /// Distance distance in meters between updates
24 | /// Include heading or not
25 | /// Optional settings (iOS only)
26 | Task StartListeningAsync(TimeSpan minimumTime, double minimumDistance, bool includeHeading = false, ListenerSettings listenerSettings = null);
27 | ```
28 |
29 | `ListenerSettings` are details more in the [Background Updates](BackgroundUpdates.md) documentation.
30 |
31 | UWP Note: How the Geolocator works you must either set the `minTime` or the `minDistance`. Setting both means that `minDistance` will take precedence between the two. You can read more on the [Windows blog](https://blogs.windows.com/buildingapps/2012/12/03/geoposition-advanced-tracking-scenarios-for-windows-phone-8/#81dhJ7lK83WcPgT2.97).
32 |
33 | ### Position Changed Event
34 |
35 | ```csharp
36 | ///
37 | /// Position changed event handler
38 | ///
39 | event EventHandler PositionChanged;
40 | ```
41 | These event args have one property of `Position` that is the new position that has been detected.
42 |
43 |
44 | ### Position Error Event
45 | If an error occures you will be notified by this event. It is best practice to stop listening and start listening again after handling the error.
46 |
47 | ```csharp
48 | ///
49 | /// Position error event handler
50 | ///
51 | event EventHandler PositionError;
52 | ```
53 |
54 | ### Stop Listening
55 | When you are all done you can stop listening for changes.
56 |
57 | ```csharp
58 | ///
59 | /// Stop listening
60 | ///
61 | /// If successfully stopped
62 | Task StopListeningAsync();
63 | ```
64 |
65 | Example:
66 | ```csharp
67 | async Task StartListening()
68 | {
69 | if(CrossGeolocator.Current.IsListening)
70 | return;
71 |
72 | await CrossGeolocator.Current.StartListeningAsync(TimeSpan.FromSeconds(5), 10, true);
73 |
74 | CrossGeolocator.Current.PositionChanged += PositionChanged;
75 | CrossGeolocator.Current.PositionError += PositionError;
76 | }
77 |
78 | private void PositionChanged(object sender, PositionEventArgs e)
79 | {
80 |
81 | //If updating the UI, ensure you invoke on main thread
82 | var position = e.Position;
83 | var output = "Full: Lat: " + position.Latitude + " Long: " + position.Longitude;
84 | output += "\n" + $"Time: {position.Timestamp}";
85 | output += "\n" + $"Heading: {position.Heading}";
86 | output += "\n" + $"Speed: {position.Speed}";
87 | output += "\n" + $"Accuracy: {position.Accuracy}";
88 | output += "\n" + $"Altitude: {position.Altitude}";
89 | output += "\n" + $"Altitude Accuracy: {position.AltitudeAccuracy}";
90 | Debug.WriteLine(output);
91 | }
92 |
93 | private void PositionError(object sender, PositionErrorEventArgs e)
94 | {
95 | Debug.WriteLine(e.Error);
96 | //Handle event here for errors
97 | }
98 |
99 | async Task StopListening()
100 | {
101 | if(!CrossGeolocator.Current.IsListening)
102 | return;
103 |
104 | await CrossGeolocator.Current.StopListening);
105 |
106 | CrossGeolocator.Current.PositionChanged -= PositionChanged;
107 | CrossGeolocator.Current.PositionError -= PositionError;
108 | }
109 | ```
110 |
111 |
112 |
113 | <= Back to [Table of Contents](README.md)
--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------
1 | ## Documentation
2 |
3 | Here you will find detailed documentation on setting up and using the Geolocator Plugin for Xamarin and Windows
4 |
5 | ### Table of Contents
6 | * [Getting Started](GettingStarted.md)
7 | * [Getting Current Location](CurrentLocation.md)
8 | * [Listing For Location Changes](LocationChanges.md)
9 | * [Background Updates](BackgroundUpdates.md)
10 | * [Geocoding](Geocoding.md)
11 | * [Architecture](Architecture.md)
12 | * [FAQ & Common Issues](FAQ.md)
--------------------------------------------------------------------------------
/docs/_config.yml:
--------------------------------------------------------------------------------
1 | theme: jekyll-theme-midnight
--------------------------------------------------------------------------------
/install-android-sdk.ps1:
--------------------------------------------------------------------------------
1 | $AndroidToolPath = "${env:ProgramFiles(x86)}\Android\android-sdk\tools\android"
2 | #$AndroidToolPath = "$env:localappdata\Android\android-sdk\tools\android"
3 |
4 | Function Get-AndroidSDKs() {
5 | $output = & $AndroidToolPath list sdk --all
6 | $sdks = $output |% {
7 | if ($_ -match '(?\d+)- (?.+), revision (?[\d\.]+)') {
8 | $sdk = New-Object PSObject
9 | Add-Member -InputObject $sdk -MemberType NoteProperty -Name Index -Value $Matches.index
10 | Add-Member -InputObject $sdk -MemberType NoteProperty -Name Name -Value $Matches.sdk
11 | Add-Member -InputObject $sdk -MemberType NoteProperty -Name Revision -Value $Matches.revision
12 | $sdk
13 | }
14 | }
15 | $sdks
16 | }
17 |
18 | Function Install-AndroidSDK() {
19 | [CmdletBinding()]
20 | Param(
21 | [Parameter(Mandatory=$true, Position=0)]
22 | [PSObject[]]$sdks
23 | )
24 |
25 | $sdkIndexes = $sdks |% { $_.Index }
26 | $sdkIndexArgument = [string]::Join(',', $sdkIndexes)
27 | Echo 'y' | & $AndroidToolPath update sdk -u -a -t $sdkIndexArgument
28 | }
29 |
30 | $sdks = Get-AndroidSDKs |? { $_.name -like 'sdk platform*API 15*' -or $_.name -like 'google apis*api 15' }
31 | Install-AndroidSDK -sdks $sdks
--------------------------------------------------------------------------------
/nuget/Plugin.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Xam.Plugin.Geolocator
5 | $version$
6 | Geolocator Plugin for Xamarin and Windows
7 | James Montemagno
8 | James Montemagno
9 | https://github.com/jamesmontemagno/GeolocatorPlugin/blob/master/LICENSE
10 | https://github.com/jamesmontemagno/GeolocatorPlugin
11 | http://www.refractored.com/images/plugin_icon_geolocator.png
12 |
13 | false
14 |
15 | Easily access geolocation across Xamarin.iOS, Xamarin.Android, and Windows.
16 |
17 | Easly access geolocation across Xamarin.iOS, Xamarin.Android, and Windows. View full project page for README
18 |
19 |
20 | Please see: https://raw.githubusercontent.com/jamesmontemagno/GeolocatorPlugin/master/CHANGELOG.md
21 |
22 | xamarin, geolocator, geolocation, gps, pcl, xam.pcl, plugin, plugin for xamarin, windows phone, winphone, wp8, winrt, android, xamarin.forms, ios
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
--------------------------------------------------------------------------------
/nuget/readme.txt:
--------------------------------------------------------------------------------
1 | Geolocator Readme
2 |
3 | For latest changes: https://github.com/jamesmontemagno/GeolocatorPlugin/blob/master/CHANGELOG.md
4 |
--------------------------------------------------------------------------------
/samples/GeolocatorSample/GeolocatorSample.Droid/Assets/AboutAssets.txt:
--------------------------------------------------------------------------------
1 | Any raw assets you want to be deployed with your application can be placed in
2 | this directory (and child directories) and given a Build Action of "AndroidAsset".
3 |
4 | These files will be deployed with you package and will be accessible using Android's
5 | AssetManager, like this:
6 |
7 | public class ReadAsset : Activity
8 | {
9 | protected override void OnCreate (Bundle bundle)
10 | {
11 | base.OnCreate (bundle);
12 |
13 | InputStream input = Assets.Open ("my_asset.txt");
14 | }
15 | }
16 |
17 | Additionally, some Android functions will automatically load asset files:
18 |
19 | Typeface tf = Typeface.CreateFromAsset (Context.Assets, "fonts/samplefont.ttf");
20 |
--------------------------------------------------------------------------------
/samples/GeolocatorSample/GeolocatorSample.Droid/GeolocatorSample.Droid.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | 8.0.30703
7 | 2.0
8 | {FD7768FC-ECB7-4E9C-AFBB-ADEB949B2748}
9 | {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
10 | Library
11 | Properties
12 | GeolocatorSample.Droid
13 | GeolocatorSample.Droid
14 | 512
15 | true
16 | Resources\Resource.Designer.cs
17 | Off
18 | Properties\AndroidManifest.xml
19 | false
20 | armeabi,armeabi-v7a,x86
21 |
22 |
23 |
24 |
25 |
26 |
27 | v8.1
28 |
29 |
30 | true
31 | full
32 | false
33 | bin\Debug\
34 | DEBUG;TRACE
35 | prompt
36 | 4
37 | True
38 | None
39 |
40 |
41 | pdbonly
42 | true
43 | bin\Release\
44 | TRACE
45 | prompt
46 | 4
47 | False
48 | SdkOnly
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 | Designer
68 |
69 |
70 | Designer
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 | GeolocatorSample
88 |
89 |
90 |
91 |
92 | 4.0.2-beta
93 |
94 |
95 | 4.5.3-beta
96 |
97 |
98 | 3.3.0.967583
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
116 |
--------------------------------------------------------------------------------
/samples/GeolocatorSample/GeolocatorSample.Droid/MainActivity.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | using Android.App;
4 | using Android.Content.PM;
5 | using Android.Runtime;
6 | using Android.Views;
7 | using Android.Widget;
8 | using Android.OS;
9 | using Plugin.Permissions;
10 | using Xamarin.Forms.Platform.Android;
11 |
12 | namespace GeolocatorSample.Droid
13 | {
14 | [Activity(Label = "GeolocatorSample", Icon = "@drawable/icon", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
15 | public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
16 | {
17 | protected override void OnCreate(Bundle bundle)
18 | {
19 | FormsAppCompatActivity.ToolbarResource = Resource.Layout.Toolbar;
20 | FormsAppCompatActivity.TabLayoutResource = Resource.Layout.Tabbar;
21 |
22 | base.OnCreate(bundle);
23 |
24 | Plugin.CurrentActivity.CrossCurrentActivity.Current.Init(this, bundle);
25 | global::Xamarin.Forms.Forms.Init(this, bundle);
26 | LoadApplication(new App());
27 | }
28 |
29 | public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
30 | {
31 | PermissionsImplementation.Current.OnRequestPermissionsResult(requestCode, permissions, grantResults);
32 | }
33 | }
34 | }
35 |
36 |
--------------------------------------------------------------------------------
/samples/GeolocatorSample/GeolocatorSample.Droid/Properties/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/samples/GeolocatorSample/GeolocatorSample.Droid/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 | using Android.App;
5 |
6 | // General Information about an assembly is controlled through the following
7 | // set of attributes. Change these attribute values to modify the information
8 | // associated with an assembly.
9 | [assembly: AssemblyTitle("GeolocatorSample.Droid")]
10 | [assembly: AssemblyDescription("")]
11 | [assembly: AssemblyConfiguration("")]
12 | [assembly: AssemblyCompany("")]
13 | [assembly: AssemblyProduct("GeolocatorSample.Droid")]
14 | [assembly: AssemblyCopyright("Copyright © 2014")]
15 | [assembly: AssemblyTrademark("")]
16 | [assembly: AssemblyCulture("")]
17 | [assembly: ComVisible(false)]
18 |
19 | // Version information for an assembly consists of the following four values:
20 | //
21 | // Major Version
22 | // Minor Version
23 | // Build Number
24 | // Revision
25 | //
26 | // You can specify all the values or you can default the Build and Revision Numbers
27 | // by using the '*' as shown below:
28 | // [assembly: AssemblyVersion("1.0.*")]
29 | [assembly: AssemblyVersion("1.0.0.0")]
30 | [assembly: AssemblyFileVersion("1.0.0.0")]
31 |
32 | // Add some common permissions, these can be removed if not needed
33 | [assembly: UsesPermission(Android.Manifest.Permission.Internet)]
34 | [assembly: UsesPermission(Android.Manifest.Permission.WriteExternalStorage)]
35 |
--------------------------------------------------------------------------------
/samples/GeolocatorSample/GeolocatorSample.Droid/Resources/AboutResources.txt:
--------------------------------------------------------------------------------
1 | Images, layout descriptions, binary blobs and string dictionaries can be included
2 | in your application as resource files. Various Android APIs are designed to
3 | operate on the resource IDs instead of dealing with images, strings or binary blobs
4 | directly.
5 |
6 | For example, a sample Android app that contains a user interface layout (main.xml),
7 | an internationalization string table (strings.xml) and some icons (drawable-XXX/icon.png)
8 | would keep its resources in the "Resources" directory of the application:
9 |
10 | Resources/
11 | drawable-hdpi/
12 | icon.png
13 |
14 | drawable-ldpi/
15 | icon.png
16 |
17 | drawable-mdpi/
18 | icon.png
19 |
20 | layout/
21 | main.xml
22 |
23 | values/
24 | strings.xml
25 |
26 | In order to get the build system to recognize Android resources, set the build action to
27 | "AndroidResource". The native Android APIs do not operate directly with filenames, but
28 | instead operate on resource IDs. When you compile an Android application that uses resources,
29 | the build system will package the resources for distribution and generate a class called
30 | "Resource" that contains the tokens for each one of the resources included. For example,
31 | for the above Resources layout, this is what the Resource class would expose:
32 |
33 | public class Resource {
34 | public class drawable {
35 | public const int icon = 0x123;
36 | }
37 |
38 | public class layout {
39 | public const int main = 0x456;
40 | }
41 |
42 | public class strings {
43 | public const int first_string = 0xabc;
44 | public const int second_string = 0xbcd;
45 | }
46 | }
47 |
48 | You would then use R.drawable.icon to reference the drawable/icon.png file, or Resource.layout.main
49 | to reference the layout/main.xml file, or Resource.strings.first_string to reference the first
50 | string in the dictionary file values/strings.xml.
51 |
--------------------------------------------------------------------------------
/samples/GeolocatorSample/GeolocatorSample.Droid/Resources/drawable-hdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jamesmontemagno/GeolocatorPlugin/f0b80019c9f127d03341bb6e191dbf58ac262580/samples/GeolocatorSample/GeolocatorSample.Droid/Resources/drawable-hdpi/icon.png
--------------------------------------------------------------------------------
/samples/GeolocatorSample/GeolocatorSample.Droid/Resources/drawable-xhdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jamesmontemagno/GeolocatorPlugin/f0b80019c9f127d03341bb6e191dbf58ac262580/samples/GeolocatorSample/GeolocatorSample.Droid/Resources/drawable-xhdpi/icon.png
--------------------------------------------------------------------------------
/samples/GeolocatorSample/GeolocatorSample.Droid/Resources/drawable-xxhdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jamesmontemagno/GeolocatorPlugin/f0b80019c9f127d03341bb6e191dbf58ac262580/samples/GeolocatorSample/GeolocatorSample.Droid/Resources/drawable-xxhdpi/icon.png
--------------------------------------------------------------------------------
/samples/GeolocatorSample/GeolocatorSample.Droid/Resources/drawable/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jamesmontemagno/GeolocatorPlugin/f0b80019c9f127d03341bb6e191dbf58ac262580/samples/GeolocatorSample/GeolocatorSample.Droid/Resources/drawable/icon.png
--------------------------------------------------------------------------------
/samples/GeolocatorSample/GeolocatorSample.Droid/Resources/layout/Tabbar.axml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/samples/GeolocatorSample/GeolocatorSample.Droid/Resources/layout/Toolbar.axml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/samples/GeolocatorSample/GeolocatorSample.Droid/Resources/values-v21/style.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
--------------------------------------------------------------------------------
/samples/GeolocatorSample/GeolocatorSample.Droid/Resources/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #2196F3
4 | #1976D2
5 | #FFC107
6 | #F5F5F5
7 |
--------------------------------------------------------------------------------
/samples/GeolocatorSample/GeolocatorSample.Droid/Resources/values/style.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
12 |
--------------------------------------------------------------------------------
/samples/GeolocatorSample/GeolocatorSample.iOS/AppDelegate.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 |
5 | using Foundation;
6 | using UIKit;
7 |
8 | namespace GeolocatorSample.iOS
9 | {
10 | // The UIApplicationDelegate for the application. This class is responsible for launching the
11 | // User Interface of the application, as well as listening (and optionally responding) to
12 | // application events from iOS.
13 | [Register("AppDelegate")]
14 | public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
15 | {
16 | //
17 | // This method is invoked when the application has loaded and is ready to run. In this
18 | // method you should instantiate the window, load the UI into it and then make the window
19 | // visible.
20 | //
21 | // You have 17 seconds to return from this method, or iOS will terminate your application.
22 | //
23 | public override bool FinishedLaunching(UIApplication app, NSDictionary options)
24 | {
25 | global::Xamarin.Forms.Forms.Init();
26 | LoadApplication(new App());
27 |
28 | return base.FinishedLaunching(app, options);
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/samples/GeolocatorSample/GeolocatorSample.iOS/Entitlements.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/samples/GeolocatorSample/GeolocatorSample.iOS/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | UIDeviceFamily
6 |
7 | 1
8 | 2
9 |
10 | UISupportedInterfaceOrientations
11 |
12 | UIInterfaceOrientationPortrait
13 | UIInterfaceOrientationLandscapeLeft
14 | UIInterfaceOrientationLandscapeRight
15 |
16 | UISupportedInterfaceOrientations~ipad
17 |
18 | UIInterfaceOrientationPortrait
19 | UIInterfaceOrientationPortraitUpsideDown
20 | UIInterfaceOrientationLandscapeLeft
21 | UIInterfaceOrientationLandscapeRight
22 |
23 | MinimumOSVersion
24 | 6.0
25 | CFBundleDisplayName
26 | GeolocatorSample
27 | CFBundleIdentifier
28 | com.yourcompany.GeolocatorSample
29 | CFBundleVersion
30 | 1.0
31 | CFBundleIconFiles
32 |
33 | Icon-60@2x
34 | Icon-60@3x
35 | Icon-76
36 | Icon-76@2x
37 | Default
38 | Default@2x
39 | Default-568h@2x
40 | Default-Portrait
41 | Default-Portrait@2x
42 | Icon-Small-40
43 | Icon-Small-40@2x
44 | Icon-Small-40@3x
45 | Icon-Small
46 | Icon-Small@2x
47 | Icon-Small@3x
48 |
49 | UILaunchStoryboardName
50 | LaunchScreen
51 | NSLocationWhenInUseUsageDescription
52 | This app needs access to location when open.
53 | NSLocationAlwaysUsageDescription
54 | This app needs access to location when in the background.
55 | NSLocationAlwaysAndWhenInUseUsageDescription
56 | This app needs access to location when open and in the background.
57 | UIBackgroundModes
58 |
59 | location
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/samples/GeolocatorSample/GeolocatorSample.iOS/Main.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 |
5 | using Foundation;
6 | using UIKit;
7 |
8 | namespace GeolocatorSample.iOS
9 | {
10 | public class Application
11 | {
12 | // This is the main entry point of the application.
13 | static void Main(string[] args)
14 | {
15 | // if you want to use a different Application Delegate class from "AppDelegate"
16 | // you can specify it here.
17 | UIApplication.Main(args, null, "AppDelegate");
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/samples/GeolocatorSample/GeolocatorSample.iOS/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("GeolocatorSample.iOS")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("GeolocatorSample.iOS")]
13 | [assembly: AssemblyCopyright("Copyright © 2014")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("72bdc44f-c588-44f3-b6df-9aace7daafdd")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/samples/GeolocatorSample/GeolocatorSample.iOS/Resources/Default-568h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jamesmontemagno/GeolocatorPlugin/f0b80019c9f127d03341bb6e191dbf58ac262580/samples/GeolocatorSample/GeolocatorSample.iOS/Resources/Default-568h@2x.png
--------------------------------------------------------------------------------
/samples/GeolocatorSample/GeolocatorSample.iOS/Resources/Default-Portrait.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jamesmontemagno/GeolocatorPlugin/f0b80019c9f127d03341bb6e191dbf58ac262580/samples/GeolocatorSample/GeolocatorSample.iOS/Resources/Default-Portrait.png
--------------------------------------------------------------------------------
/samples/GeolocatorSample/GeolocatorSample.iOS/Resources/Default-Portrait@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jamesmontemagno/GeolocatorPlugin/f0b80019c9f127d03341bb6e191dbf58ac262580/samples/GeolocatorSample/GeolocatorSample.iOS/Resources/Default-Portrait@2x.png
--------------------------------------------------------------------------------
/samples/GeolocatorSample/GeolocatorSample.iOS/Resources/Default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jamesmontemagno/GeolocatorPlugin/f0b80019c9f127d03341bb6e191dbf58ac262580/samples/GeolocatorSample/GeolocatorSample.iOS/Resources/Default.png
--------------------------------------------------------------------------------
/samples/GeolocatorSample/GeolocatorSample.iOS/Resources/Default@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jamesmontemagno/GeolocatorPlugin/f0b80019c9f127d03341bb6e191dbf58ac262580/samples/GeolocatorSample/GeolocatorSample.iOS/Resources/Default@2x.png
--------------------------------------------------------------------------------
/samples/GeolocatorSample/GeolocatorSample.iOS/Resources/Icon-60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jamesmontemagno/GeolocatorPlugin/f0b80019c9f127d03341bb6e191dbf58ac262580/samples/GeolocatorSample/GeolocatorSample.iOS/Resources/Icon-60@2x.png
--------------------------------------------------------------------------------
/samples/GeolocatorSample/GeolocatorSample.iOS/Resources/Icon-60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jamesmontemagno/GeolocatorPlugin/f0b80019c9f127d03341bb6e191dbf58ac262580/samples/GeolocatorSample/GeolocatorSample.iOS/Resources/Icon-60@3x.png
--------------------------------------------------------------------------------
/samples/GeolocatorSample/GeolocatorSample.iOS/Resources/Icon-76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jamesmontemagno/GeolocatorPlugin/f0b80019c9f127d03341bb6e191dbf58ac262580/samples/GeolocatorSample/GeolocatorSample.iOS/Resources/Icon-76.png
--------------------------------------------------------------------------------
/samples/GeolocatorSample/GeolocatorSample.iOS/Resources/Icon-76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jamesmontemagno/GeolocatorPlugin/f0b80019c9f127d03341bb6e191dbf58ac262580/samples/GeolocatorSample/GeolocatorSample.iOS/Resources/Icon-76@2x.png
--------------------------------------------------------------------------------
/samples/GeolocatorSample/GeolocatorSample.iOS/Resources/Icon-Small-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jamesmontemagno/GeolocatorPlugin/f0b80019c9f127d03341bb6e191dbf58ac262580/samples/GeolocatorSample/GeolocatorSample.iOS/Resources/Icon-Small-40.png
--------------------------------------------------------------------------------
/samples/GeolocatorSample/GeolocatorSample.iOS/Resources/Icon-Small-40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jamesmontemagno/GeolocatorPlugin/f0b80019c9f127d03341bb6e191dbf58ac262580/samples/GeolocatorSample/GeolocatorSample.iOS/Resources/Icon-Small-40@2x.png
--------------------------------------------------------------------------------
/samples/GeolocatorSample/GeolocatorSample.iOS/Resources/Icon-Small-40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jamesmontemagno/GeolocatorPlugin/f0b80019c9f127d03341bb6e191dbf58ac262580/samples/GeolocatorSample/GeolocatorSample.iOS/Resources/Icon-Small-40@3x.png
--------------------------------------------------------------------------------
/samples/GeolocatorSample/GeolocatorSample.iOS/Resources/Icon-Small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jamesmontemagno/GeolocatorPlugin/f0b80019c9f127d03341bb6e191dbf58ac262580/samples/GeolocatorSample/GeolocatorSample.iOS/Resources/Icon-Small.png
--------------------------------------------------------------------------------
/samples/GeolocatorSample/GeolocatorSample.iOS/Resources/Icon-Small@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jamesmontemagno/GeolocatorPlugin/f0b80019c9f127d03341bb6e191dbf58ac262580/samples/GeolocatorSample/GeolocatorSample.iOS/Resources/Icon-Small@2x.png
--------------------------------------------------------------------------------
/samples/GeolocatorSample/GeolocatorSample.iOS/Resources/Icon-Small@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jamesmontemagno/GeolocatorPlugin/f0b80019c9f127d03341bb6e191dbf58ac262580/samples/GeolocatorSample/GeolocatorSample.iOS/Resources/Icon-Small@3x.png
--------------------------------------------------------------------------------
/samples/GeolocatorSample/GeolocatorSample.iOS/iTunesArtwork:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jamesmontemagno/GeolocatorPlugin/f0b80019c9f127d03341bb6e191dbf58ac262580/samples/GeolocatorSample/GeolocatorSample.iOS/iTunesArtwork
--------------------------------------------------------------------------------
/samples/GeolocatorSample/GeolocatorSample.iOS/iTunesArtwork@2x:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jamesmontemagno/GeolocatorPlugin/f0b80019c9f127d03341bb6e191dbf58ac262580/samples/GeolocatorSample/GeolocatorSample.iOS/iTunesArtwork@2x
--------------------------------------------------------------------------------
/samples/GeolocatorSample/GeolocatorSample/App.cs:
--------------------------------------------------------------------------------
1 | using Plugin.Geolocator;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 | using Xamarin.Forms;
7 |
8 | namespace GeolocatorSample
9 | {
10 | public class App : Application
11 | {
12 | public App()
13 | {
14 |
15 | // The root page of your application
16 | MainPage = new NavigationPage(new HomePage());
17 | }
18 |
19 | protected override void OnStart()
20 | {
21 | // Handle when your app starts
22 | }
23 |
24 | protected override void OnSleep()
25 | {
26 | // Handle when your app sleeps
27 | }
28 |
29 | protected override void OnResume()
30 | {
31 | // Handle when your app resumes
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/samples/GeolocatorSample/GeolocatorSample/GeolocatorSample.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | netstandard2.0
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | MSBuild:Compile
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/samples/GeolocatorSample/GeolocatorSample/HomePage.xaml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
67 |
68 |
69 |
70 |
71 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
103 |
104 |
105 |
106 |
107 |
109 |
110 |
111 |
112 |
113 |
114 |
115 | Other
116 | Automotive Navigation
117 | Fitness
118 | Other Navigation
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
--------------------------------------------------------------------------------
/samples/GeolocatorSample/GeolocatorSample/Utils.cs:
--------------------------------------------------------------------------------
1 | using Plugin.Permissions;
2 | using Plugin.Permissions.Abstractions;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Linq;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 | using Xamarin.Forms;
9 |
10 | namespace GeolocatorSample
11 | {
12 | public static class Utils
13 | {
14 | public static async Task CheckPermissions(Permission permission)
15 | {
16 | var permissionStatus = await CrossPermissions.Current.CheckPermissionStatusAsync(permission);
17 | bool request = false;
18 | if (permissionStatus == PermissionStatus.Denied)
19 | {
20 | if (Device.RuntimePlatform == Device.iOS)
21 | {
22 |
23 | var title = $"{permission} Permission";
24 | var question = $"To use this plugin the {permission} permission is required. Please go into Settings and turn on {permission} for the app.";
25 | var positive = "Settings";
26 | var negative = "Maybe Later";
27 | var task = Application.Current?.MainPage?.DisplayAlert(title, question, positive, negative);
28 | if (task == null)
29 | return false;
30 |
31 | var result = await task;
32 | if (result)
33 | {
34 | CrossPermissions.Current.OpenAppSettings();
35 | }
36 |
37 | return false;
38 | }
39 |
40 | request = true;
41 |
42 | }
43 |
44 | if (request || permissionStatus != PermissionStatus.Granted)
45 | {
46 | var newStatus = await CrossPermissions.Current.RequestPermissionsAsync(permission);
47 | if (newStatus.ContainsKey(permission) && newStatus[permission] != PermissionStatus.Granted)
48 | {
49 | var title = $"{permission} Permission";
50 | var question = $"To use the plugin the {permission} permission is required.";
51 | var positive = "Settings";
52 | var negative = "Maybe Later";
53 | var task = Application.Current?.MainPage?.DisplayAlert(title, question, positive, negative);
54 | if (task == null)
55 | return false;
56 |
57 | var result = await task;
58 | if (result)
59 | {
60 | CrossPermissions.Current.OpenAppSettings();
61 | }
62 | return false;
63 | }
64 | }
65 |
66 | return true;
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/src/Geolocator.Plugin/Abstractions/ActivityType.shared.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Plugin.Geolocator.Abstractions
4 | {
5 | ///
6 | /// Activity type (iOS only). Used to determine when to automatically pause location updates.
7 | ///
8 | public enum ActivityType
9 | {
10 | ///
11 | /// GPS is being used for an unknown activity.
12 | ///
13 | Other,
14 |
15 | ///
16 | /// GPS is being used specifically during vehicular navigation to track location changes to the automobile. This activity might cause location updates to be paused only when the vehicle does not move for an extended period of time.
17 | ///
18 | AutomotiveNavigation,
19 |
20 | ///
21 | /// GPS is being used to track any pedestrian-related activity. This activity might cause location updates to be paused only when the user does not move a significant distance over a period of time.
22 | ///
23 | Fitness,
24 |
25 | ///
26 | /// GPS is being used to track movements for other types of vehicular navigation that are not automobile related. For example, you would use this to track navigation by boat, train, or plane. Do not use this type for pedestrian navigation tracking. This activity might cause location updates to be paused only when the vehicle does not move a significant distance over a period of time.
27 | ///
28 | OtherNavigation
29 | }
30 | }
--------------------------------------------------------------------------------
/src/Geolocator.Plugin/Abstractions/Address.shared.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Plugin.Geolocator.Abstractions
4 | {
5 | public class Address
6 | {
7 | public Address()
8 | {
9 | }
10 |
11 | public Address(Address address)
12 | {
13 | if (address == null)
14 | throw new ArgumentNullException(nameof(address));
15 |
16 | CountryCode = address.CountryCode;
17 | CountryName = address.CountryName;
18 | Latitude = address.Latitude;
19 | Longitude = address.Longitude;
20 | FeatureName = address.FeatureName;
21 | PostalCode = address.PostalCode;
22 | SubLocality = address.SubLocality;
23 | Thoroughfare = address.Thoroughfare;
24 | SubThoroughfare = address.SubThoroughfare;
25 | SubAdminArea = address.SubAdminArea;
26 | AdminArea = address.AdminArea;
27 | }
28 |
29 | ///
30 | /// Gets or sets the latitude.
31 | ///
32 | public double Latitude { get; set; }
33 |
34 | ///
35 | /// Gets or sets the longitude.
36 | ///
37 | public double Longitude { get; set; }
38 |
39 | ///
40 | /// Gets or sets the country ISO code.
41 | ///
42 | public string CountryCode { get; set; }
43 |
44 | ///
45 | /// Gets or sets the country name.
46 | ///
47 | public string CountryName { get; set; }
48 |
49 | ///
50 | /// Gets or sets a featured name.
51 | ///
52 | public string FeatureName { get; set; }
53 |
54 | ///
55 | /// Gets or sets a postal code.
56 | ///
57 | public string PostalCode { get; set; }
58 |
59 | ///
60 | /// Gets or sets a sub locality.
61 | ///
62 | public string SubLocality { get; set; }
63 |
64 | ///
65 | /// Gets or sets a street name.
66 | ///
67 | public string Thoroughfare { get; set; }
68 |
69 | ///
70 | /// Gets or sets optional info: sub street or region.
71 | ///
72 | public string SubThoroughfare { get; set; }
73 |
74 | ///
75 | /// Gets or sets a city/town.
76 | ///
77 | public string Locality { get; set; }
78 |
79 | ///
80 | /// Gets or sets the administrative area name of the address, for example, "CA", or null if it is unknown
81 | ///
82 | public string AdminArea { get; set; }
83 |
84 | ///
85 | /// Gets or sets the sub-administrative area name of the address, for example, "Santa Clara County", or null if it is unknown
86 | ///
87 | public string SubAdminArea { get; set; }
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/src/Geolocator.Plugin/Abstractions/GeolocatorUtils.shared.cs:
--------------------------------------------------------------------------------
1 | using static System.Math;
2 |
3 | namespace Plugin.Geolocator.Abstractions
4 | {
5 | ///
6 | /// Geolocator Plugin Utililities
7 | ///
8 | public static class GeolocatorUtils
9 | {
10 | ///
11 | /// Calculates the distance in miles
12 | ///
13 | /// The distance.
14 | /// Latitude start.
15 | /// Longitude start.
16 | /// Latitude end.
17 | /// Longitude end.
18 | /// Units to return
19 | public static double CalculateDistance(double latitudeStart, double longitudeStart,
20 | double latitudeEnd, double longitudeEnd, DistanceUnits units = DistanceUnits.Miles)
21 | {
22 | if (latitudeEnd == latitudeStart && longitudeEnd == longitudeStart)
23 | return 0;
24 |
25 | var rlat1 = PI * latitudeStart / 180.0;
26 | var rlat2 = PI * latitudeEnd / 180.0;
27 | var theta = longitudeStart - longitudeEnd;
28 | var rtheta = PI * theta / 180.0;
29 | var dist = Sin(rlat1) * Sin(rlat2) + Cos(rlat1) * Cos(rlat2) * Cos(rtheta);
30 | dist = Acos(dist);
31 | dist = dist * 180.0 / PI;
32 | var final = dist * 60.0 * 1.1515;
33 | if (double.IsNaN(final) || double.IsInfinity(final) || double.IsNegativeInfinity(final) ||
34 | double.IsPositiveInfinity(final) || final < 0)
35 | return 0;
36 |
37 | if (units == DistanceUnits.Kilometers)
38 | return MilesToKilometers(final);
39 |
40 | return final;
41 | }
42 |
43 |
44 | ///
45 | /// Calculates the distance in miles
46 | ///
47 | /// The distance.
48 | /// Start position
49 | /// End Position.
50 | /// Units to return
51 | public static double CalculateDistance(this Position positionStart, Position positionEnd, DistanceUnits units = DistanceUnits.Miles) =>
52 | CalculateDistance(positionStart.Latitude, positionStart.Longitude, positionEnd.Latitude, positionEnd.Longitude, units);
53 |
54 |
55 |
56 | ///
57 | /// Convert Miles to Kilometers
58 | ///
59 | ///
60 | ///
61 | public static double MilesToKilometers(double miles) => miles * 1.609344;
62 |
63 | ///
64 | /// Convert Kilometers to Miles
65 | ///
66 | ///
67 | ///
68 | public static double KilometersToMiles(double kilometers) => kilometers * .62137119;
69 |
70 | ///
71 | /// Units for the distance
72 | ///
73 | public enum DistanceUnits
74 | {
75 | ///
76 | /// Kilometers
77 | ///
78 | Kilometers,
79 | ///
80 | /// Miles
81 | ///
82 | Miles
83 | }
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/src/Geolocator.Plugin/Abstractions/IGeolocator.shared.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Threading;
4 | using System.Threading.Tasks;
5 |
6 | namespace Plugin.Geolocator.Abstractions
7 | {
8 | ///
9 | /// Interface for Geolocator
10 | ///
11 | public interface IGeolocator
12 | {
13 | ///
14 | /// Position error event handler
15 | ///
16 | event EventHandler PositionError;
17 |
18 | ///
19 | /// Position changed event handler
20 | ///
21 | event EventHandler PositionChanged;
22 |
23 | ///
24 | /// Desired accuracy in meters
25 | ///
26 | double DesiredAccuracy { get; set; }
27 |
28 | ///
29 | /// Gets if you are listening for location changes
30 | ///
31 | bool IsListening { get; }
32 |
33 | ///
34 | /// Gets if device supports heading
35 | ///
36 | bool SupportsHeading { get; }
37 |
38 | ///
39 | /// Gets if geolocation is available on device
40 | ///
41 | bool IsGeolocationAvailable { get; }
42 |
43 | ///
44 | /// Gets if geolocation is enabled on device
45 | ///
46 | bool IsGeolocationEnabled { get; }
47 |
48 |
49 |
50 | ///
51 | /// Gets the last known and most accurate location.
52 | /// This is usually cached and best to display first before querying for full position.
53 | ///
54 | /// Best and most recent location or null if none found
55 | Task GetLastKnownLocationAsync();
56 |
57 | ///
58 | /// Gets position async with specified parameters
59 | ///
60 | /// Timeout to wait, Default Infinite
61 | /// Cancelation token
62 | /// If you would like to include heading
63 | /// Position
64 | Task GetPositionAsync(TimeSpan? timeout = null, CancellationToken? token = null, bool includeHeading = false);
65 |
66 | ///
67 | /// Retrieve addresses for position.
68 | ///
69 | /// Desired position (latitude and longitude)
70 | /// Map Key required only on UWP
71 | /// Addresses of the desired position
72 | Task> GetAddressesForPositionAsync(Position position, string mapKey = null);
73 |
74 | ///
75 | /// Retrieve positions for address.
76 | ///
77 | /// Desired address
78 | /// Map Key required only on UWP
79 | /// Positions of the desired address
80 | Task> GetPositionsForAddressAsync(string address, string mapKey = null);
81 |
82 | ///
83 | /// Start listening for changes
84 | ///
85 | /// Minimum time between updates
86 | /// Distance distance in meters between updates
87 | /// Include heading or not
88 | /// Optional settings (iOS only)
89 | Task StartListeningAsync(TimeSpan minimumTime, double minimumDistance, bool includeHeading = false, ListenerSettings listenerSettings = null);
90 |
91 |
92 | ///
93 | /// Stop listening
94 | ///
95 | /// If successfully stopped
96 | Task StopListeningAsync();
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/src/Geolocator.Plugin/Abstractions/ListenerSettings.shared.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Plugin.Geolocator.Abstractions
4 | {
5 | ///
6 | /// Settings for location listening (only applies to iOS). All defaults are set as indicated in the docs for CLLocationManager.
7 | ///
8 | public class ListenerSettings
9 | {
10 | ///
11 | /// Gets or sets whether background location updates should be allowed (>= iOS 9). Default: false
12 | ///
13 | public bool AllowBackgroundUpdates { get; set; } = false;
14 |
15 | ///
16 | /// Gets or sets whether location updates should be paused automatically when the location is unlikely to change (>= iOS 6). Default: true
17 | ///
18 | public bool PauseLocationUpdatesAutomatically { get; set; } = true;
19 |
20 | ///
21 | /// Gets or sets the activity type that should be used to determine when to automatically pause location updates (>= iOS 6). Default: ActivityType.Other
22 | ///
23 | public ActivityType ActivityType { get; set; } = ActivityType.Other;
24 |
25 | ///
26 | /// Gets or sets whether the location manager should only listen for significant changes in location, rather than continuous listening (>= iOS 4). Default: false
27 | ///
28 | public bool ListenForSignificantChanges { get; set; } = false;
29 |
30 | ///
31 | /// Gets or sets whether the location manager should defer location updates until an energy efficient time arrives, or distance and time criteria are met (>= iOS 6). Default: false
32 | ///
33 | public bool DeferLocationUpdates { get; set; } = false;
34 |
35 | ///
36 | /// If deferring location updates, the minimum distance to travel before updates are delivered (>= iOS 6). Set to null for indefinite wait. Default: 500
37 | ///
38 | public double? DeferralDistanceMeters { get; set; } = 500;
39 |
40 | ///
41 | /// If deferring location updates, the minimum time that should elapse before updates are delivered (>= iOS 6). Set to null for indefinite wait. Default: 5 minutes
42 | ///
43 | /// The time between updates (default: 5 minutes).
44 | public TimeSpan? DeferralTime { get; set; } = TimeSpan.FromMinutes(5);
45 |
46 | ///
47 | /// A Boolean indicating whether the status bar changes its appearance when an app uses location services in the background. (>= iOS 11). Default: false
48 | ///
49 | public bool ShowsBackgroundLocationIndicator { get; set; } = false;
50 |
51 | ///
52 | /// A boolean indicating whether Always permission should be required to start location listening
53 | ///
54 | public bool RequireLocationAlwaysPermission { get; set; } = false;
55 | }
56 | }
--------------------------------------------------------------------------------
/src/Geolocator.Plugin/Android/GeolocationContinuousListener.android.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading;
3 | using Android.Locations;
4 | using Android.OS;
5 | using System.Collections.Generic;
6 |
7 | using Plugin.Geolocator.Abstractions;
8 | using Android.Runtime;
9 |
10 | namespace Plugin.Geolocator
11 | {
12 | [Preserve(AllMembers = true)]
13 | internal class GeolocationContinuousListener
14 | : Java.Lang.Object, ILocationListener
15 | {
16 | IList providers;
17 | readonly HashSet activeProviders = new HashSet();
18 | readonly LocationManager manager;
19 |
20 | string activeProvider;
21 | Location lastLocation;
22 | TimeSpan timePeriod;
23 |
24 | public GeolocationContinuousListener(LocationManager manager, TimeSpan timePeriod, IList providers)
25 | {
26 | this.manager = manager;
27 | this.timePeriod = timePeriod;
28 | this.providers = providers;
29 |
30 | foreach (string p in providers)
31 | {
32 | if (manager.IsProviderEnabled(p))
33 | activeProviders.Add(p);
34 | }
35 | }
36 |
37 | public event EventHandler PositionError;
38 | public event EventHandler PositionChanged;
39 |
40 | public void OnLocationChanged(Location location)
41 | {
42 | if (location.Provider != activeProvider)
43 | {
44 | if (activeProvider != null && manager.IsProviderEnabled(activeProvider))
45 | {
46 | var pr = manager.GetProvider(location.Provider);
47 | var lapsed = GetTimeSpan(location.Time) - GetTimeSpan(lastLocation.Time);
48 |
49 | if (pr.Accuracy > manager.GetProvider(activeProvider).Accuracy
50 | && lapsed < timePeriod.Add(timePeriod))
51 | {
52 | location.Dispose();
53 | return;
54 | }
55 | }
56 |
57 | activeProvider = location.Provider;
58 | }
59 |
60 | var previous = Interlocked.Exchange(ref lastLocation, location);
61 | if (previous != null)
62 | previous.Dispose();
63 |
64 |
65 | PositionChanged?.Invoke(this, new PositionEventArgs(location.ToPosition()));
66 | }
67 |
68 | public void OnProviderDisabled(string provider)
69 | {
70 | if (provider == LocationManager.PassiveProvider)
71 | return;
72 |
73 | lock (activeProviders)
74 | {
75 | if (activeProviders.Remove(provider) && activeProviders.Count == 0)
76 | OnPositionError(new PositionErrorEventArgs(GeolocationError.PositionUnavailable));
77 | }
78 | }
79 |
80 | public void OnProviderEnabled(string provider)
81 | {
82 | if (provider == LocationManager.PassiveProvider)
83 | return;
84 |
85 | lock (activeProviders)
86 | activeProviders.Add(provider);
87 | }
88 |
89 | public void OnStatusChanged(string provider, Availability status, Bundle extras)
90 | {
91 | switch (status)
92 | {
93 | case Availability.Available:
94 | OnProviderEnabled(provider);
95 | break;
96 |
97 | case Availability.OutOfService:
98 | OnProviderDisabled(provider);
99 | break;
100 | }
101 | }
102 |
103 | private TimeSpan GetTimeSpan(long time) => new TimeSpan(TimeSpan.TicksPerMillisecond * time);
104 |
105 |
106 | private void OnPositionError(PositionErrorEventArgs e) => PositionError?.Invoke(this, e);
107 |
108 | }
109 | }
--------------------------------------------------------------------------------
/src/Geolocator.Plugin/Android/GeolocationSingleListener.android.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading.Tasks;
3 | using Android.Locations;
4 | using Android.OS;
5 | using System.Threading;
6 | using System.Collections.Generic;
7 | using Plugin.Geolocator.Abstractions;
8 | using Android.Runtime;
9 |
10 | namespace Plugin.Geolocator
11 | {
12 | [Preserve(AllMembers = true)]
13 | internal class GeolocationSingleListener
14 | : Java.Lang.Object, ILocationListener
15 | {
16 |
17 | readonly object locationSync = new object();
18 | Location bestLocation;
19 |
20 |
21 | readonly Action finishedCallback;
22 | readonly float desiredAccuracy;
23 | readonly Timer timer;
24 | readonly TaskCompletionSource completionSource = new TaskCompletionSource();
25 | HashSet activeProviders = new HashSet();
26 |
27 | public GeolocationSingleListener(LocationManager manager, float desiredAccuracy, int timeout, IEnumerable activeProviders, Action finishedCallback)
28 | {
29 | this.desiredAccuracy = desiredAccuracy;
30 | this.finishedCallback = finishedCallback;
31 |
32 | this.activeProviders = new HashSet(activeProviders);
33 |
34 | foreach (var provider in activeProviders)
35 | {
36 | var location = manager.GetLastKnownLocation(provider);
37 | if (location != null && GeolocationUtils.IsBetterLocation(location, bestLocation))
38 | bestLocation = location;
39 | }
40 |
41 |
42 | if (timeout != Timeout.Infinite)
43 | timer = new Timer(TimesUp, null, timeout, 0);
44 | }
45 |
46 | public Task Task => completionSource.Task;
47 |
48 |
49 | public void OnLocationChanged(Location location)
50 | {
51 | if (location.Accuracy <= desiredAccuracy)
52 | {
53 | Finish(location);
54 | return;
55 | }
56 |
57 | lock (locationSync)
58 | {
59 | if (GeolocationUtils.IsBetterLocation(location, bestLocation))
60 | bestLocation = location;
61 | }
62 | }
63 |
64 |
65 |
66 | public void OnProviderDisabled(string provider)
67 | {
68 | lock (activeProviders)
69 | {
70 | if (activeProviders.Remove(provider) && activeProviders.Count == 0)
71 | completionSource.TrySetException(new GeolocationException(GeolocationError.PositionUnavailable));
72 | }
73 | }
74 |
75 | public void OnProviderEnabled(string provider)
76 | {
77 | lock (activeProviders)
78 | activeProviders.Add(provider);
79 | }
80 |
81 | public void OnStatusChanged(string provider, Availability status, Bundle extras)
82 | {
83 | switch (status)
84 | {
85 | case Availability.Available:
86 | OnProviderEnabled(provider);
87 | break;
88 |
89 | case Availability.OutOfService:
90 | OnProviderDisabled(provider);
91 | break;
92 | }
93 | }
94 |
95 | public void Cancel() => completionSource.TrySetCanceled();
96 |
97 | private void TimesUp(object state)
98 | {
99 | lock (locationSync)
100 | {
101 | if (bestLocation == null)
102 | {
103 | if (completionSource.TrySetCanceled())
104 | finishedCallback?.Invoke();
105 | }
106 | else
107 | {
108 | Finish(bestLocation);
109 | }
110 | }
111 | }
112 |
113 | private void Finish(Location location)
114 | {
115 | finishedCallback?.Invoke();
116 | completionSource.TrySetResult(location.ToPosition());
117 | }
118 | }
119 | }
--------------------------------------------------------------------------------
/src/Geolocator.Plugin/Android/GeolocationUtils.android.cs:
--------------------------------------------------------------------------------
1 | using Android.Locations;
2 | using Plugin.Geolocator.Abstractions;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Linq;
6 | using Address = Plugin.Geolocator.Abstractions.Address;
7 |
8 | namespace Plugin.Geolocator
9 | {
10 | public static class GeolocationUtils
11 | {
12 |
13 | static int twoMinutes = 120000;
14 |
15 | internal static bool IsBetterLocation(Location location, Location bestLocation)
16 | {
17 |
18 | if (bestLocation == null)
19 | return true;
20 |
21 | var timeDelta = location.Time - bestLocation.Time;
22 | var isSignificantlyNewer = timeDelta > twoMinutes;
23 | var isSignificantlyOlder = timeDelta < -twoMinutes;
24 | var isNewer = timeDelta > 0;
25 |
26 | if (isSignificantlyNewer)
27 | return true;
28 |
29 | if (isSignificantlyOlder)
30 | return false;
31 |
32 | var accuracyDelta = (int)(location.Accuracy - bestLocation.Accuracy);
33 | var isLessAccurate = accuracyDelta > 0;
34 | var isMoreAccurate = accuracyDelta < 0;
35 | var isSignificantlyLessAccurage = accuracyDelta > 200;
36 |
37 | var isFromSameProvider = IsSameProvider(location.Provider, bestLocation.Provider);
38 |
39 | if (isMoreAccurate)
40 | return true;
41 |
42 | if (isNewer && !isLessAccurate)
43 | return true;
44 |
45 | if (isNewer && !isSignificantlyLessAccurage && isFromSameProvider)
46 | return true;
47 |
48 | return false;
49 |
50 |
51 | }
52 |
53 | internal static bool IsSameProvider(string provider1, string provider2)
54 | {
55 | if (provider1 == null)
56 | return provider2 == null;
57 |
58 | return provider1.Equals(provider2);
59 | }
60 |
61 | internal static Position ToPosition(this Location location)
62 | {
63 | var p = new Position();
64 |
65 | p.HasAccuracy = location.HasAccuracy;
66 | if (location.HasAccuracy)
67 | p.Accuracy = location.Accuracy;
68 |
69 | p.HasAltitude = location.HasAltitude;
70 | if (location.HasAltitude)
71 | p.Altitude = location.Altitude;
72 |
73 | p.HasHeading = location.HasBearing;
74 | if (location.HasBearing)
75 | p.Heading = location.Bearing;
76 |
77 | p.HasSpeed = location.HasSpeed;
78 | if (location.HasSpeed)
79 | p.Speed = location.Speed;
80 |
81 | p.HasLatitudeLongitude = true;
82 | p.Longitude = location.Longitude;
83 | p.Latitude = location.Latitude;
84 | p.Timestamp = location.GetTimestamp();
85 |
86 | if ((int)Android.OS.Build.VERSION.SdkInt >= 18)
87 | p.IsFromMockProvider = location.IsFromMockProvider;
88 | else
89 | p.IsFromMockProvider = false;
90 |
91 | return p;
92 | }
93 |
94 | internal static IEnumerable ToAddresses(this IEnumerable addresses)
95 | {
96 | return addresses.Select(address => new Address
97 | {
98 | Longitude = address.Longitude,
99 | Latitude = address.Latitude,
100 | FeatureName = address.FeatureName,
101 | PostalCode = address.PostalCode,
102 | SubLocality = address.SubLocality,
103 | CountryCode = address.CountryCode,
104 | CountryName = address.CountryName,
105 | Thoroughfare = address.Thoroughfare,
106 | SubThoroughfare = address.SubThoroughfare,
107 | Locality = address.Locality,
108 | AdminArea = address.AdminArea,
109 | SubAdminArea = address.SubAdminArea
110 | });
111 | }
112 |
113 | private static readonly DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
114 | internal static DateTimeOffset GetTimestamp(this Location location)
115 | {
116 | try
117 | {
118 | return new DateTimeOffset(epoch.AddMilliseconds(location.Time));
119 | }
120 | catch (Exception)
121 | {
122 | return new DateTimeOffset(epoch);
123 | }
124 | }
125 | }
126 | }
--------------------------------------------------------------------------------
/src/Geolocator.Plugin/Android/ManifestInfo.android.cs:
--------------------------------------------------------------------------------
1 | using Android.App;
2 |
3 | [assembly: UsesPermission(Android.Manifest.Permission.AccessCoarseLocation)]
4 | [assembly: UsesPermission(Android.Manifest.Permission.AccessFineLocation)]
5 | //Required when targeting Android API 21+
6 | [assembly: UsesFeature("android.hardware.location.gps")]
7 | [assembly: UsesFeature("android.hardware.location.network")]
--------------------------------------------------------------------------------
/src/Geolocator.Plugin/Apple/GeolocationSingleUpdateDelegate.apple.cs:
--------------------------------------------------------------------------------
1 |
2 | using System;
3 | using CoreLocation;
4 | using Foundation;
5 | using System.Threading.Tasks;
6 | using System.Threading;
7 | using Plugin.Geolocator.Abstractions;
8 | using System.Linq;
9 |
10 | namespace Plugin.Geolocator
11 | {
12 | [Preserve(AllMembers = true)]
13 | internal class GeolocationSingleUpdateDelegate : CLLocationManagerDelegate
14 | {
15 | bool haveLocation;
16 | readonly Position position = new Position();
17 |
18 | readonly double desiredAccuracy;
19 | readonly bool includeHeading;
20 | readonly TaskCompletionSource tcs;
21 | readonly CLLocationManager manager;
22 |
23 | public GeolocationSingleUpdateDelegate(CLLocationManager manager, double desiredAccuracy, bool includeHeading, int timeout, CancellationToken cancelToken)
24 | {
25 | this.manager = manager;
26 | tcs = new TaskCompletionSource(manager);
27 | this.desiredAccuracy = desiredAccuracy;
28 | this.includeHeading = includeHeading;
29 |
30 | if (timeout != Timeout.Infinite)
31 | {
32 | Timer t = null;
33 | t = new Timer(s =>
34 | {
35 | if (haveLocation)
36 | tcs.TrySetResult(new Position(this.position));
37 | else
38 | tcs.TrySetCanceled();
39 |
40 | StopListening();
41 | t.Dispose();
42 | }, null, timeout, 0);
43 | }
44 |
45 | #if __IOS__
46 | manager.ShouldDisplayHeadingCalibration += (CLLocationManager locationManager) =>
47 | {
48 | locationManager.DismissHeadingCalibrationDisplay();
49 | return false;
50 | };
51 | #endif
52 |
53 | cancelToken.Register(() =>
54 | {
55 | StopListening();
56 | tcs.TrySetCanceled();
57 | });
58 | }
59 |
60 | public Task Task => tcs?.Task;
61 |
62 | public override void AuthorizationChanged(CLLocationManager manager, CLAuthorizationStatus status)
63 | {
64 | // If user has services disabled, we're just going to throw an exception for consistency.
65 | if (status == CLAuthorizationStatus.Denied || status == CLAuthorizationStatus.Restricted)
66 | {
67 | StopListening();
68 | tcs.TrySetException(new GeolocationException(GeolocationError.Unauthorized));
69 | }
70 | }
71 |
72 | public override void Failed(CLLocationManager manager, NSError error)
73 | {
74 | switch ((CLError)(int)error.Code)
75 | {
76 | case CLError.Network:
77 | StopListening();
78 | tcs.SetException(new GeolocationException(GeolocationError.PositionUnavailable));
79 | break;
80 | case CLError.LocationUnknown:
81 | StopListening();
82 | tcs.TrySetException(new GeolocationException(GeolocationError.PositionUnavailable));
83 | break;
84 | }
85 | }
86 |
87 | #if __IOS__
88 | public override bool ShouldDisplayHeadingCalibration(CLLocationManager locationManager)
89 | {
90 | locationManager.DismissHeadingCalibrationDisplay();
91 | return false;
92 | }
93 | #endif
94 |
95 | #if __TVOS__
96 | public override void LocationsUpdated(CLLocationManager manager, CLLocation[] locations)
97 | {
98 | var newLocation = locations.FirstOrDefault();
99 | if (newLocation == null)
100 | return;
101 |
102 | #else
103 | public override void UpdatedLocation(CLLocationManager manager, CLLocation newLocation, CLLocation oldLocation)
104 | {
105 | #endif
106 | if (newLocation.HorizontalAccuracy < 0)
107 | return;
108 |
109 | if (haveLocation && newLocation.HorizontalAccuracy > position.Accuracy)
110 | return;
111 |
112 | position.HasAccuracy = true;
113 | position.Accuracy = newLocation.HorizontalAccuracy;
114 | position.HasAltitude = newLocation.VerticalAccuracy > -1;
115 | position.Altitude = newLocation.Altitude;
116 | position.AltitudeAccuracy = newLocation.VerticalAccuracy;
117 | position.HasLatitudeLongitude = newLocation.HorizontalAccuracy > -1;
118 | position.Latitude = newLocation.Coordinate.Latitude;
119 | position.Longitude = newLocation.Coordinate.Longitude;
120 | #if __IOS__ || __MACOS__
121 | position.HasSpeed = newLocation.Speed > -1;
122 | position.Speed = newLocation.Speed;
123 | if (includeHeading)
124 | {
125 | position.HasHeading = newLocation.Course > -1;
126 | position.Heading = newLocation.Course;
127 | }
128 | #endif
129 | try
130 | {
131 | position.Timestamp = new DateTimeOffset(newLocation.Timestamp.ToDateTime());
132 | }
133 | catch (Exception ex)
134 | {
135 | position.Timestamp = DateTimeOffset.UtcNow;
136 | }
137 | haveLocation = true;
138 | }
139 |
140 | private void StopListening()
141 | {
142 | manager.StopUpdatingLocation();
143 | }
144 | }
145 | }
146 |
--------------------------------------------------------------------------------
/src/Geolocator.Plugin/Apple/GeolocationUtils.apple.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using CoreLocation;
4 | using Address = Plugin.Geolocator.Abstractions.Address;
5 | using System;
6 | using Foundation;
7 |
8 | namespace Plugin.Geolocator
9 | {
10 | public static class GeolocationUtils
11 | {
12 | internal static IEnumerable ToAddresses(this IEnumerable addresses)
13 | {
14 | return addresses.Select(address => new Address
15 | {
16 | Longitude = address.Location.Coordinate.Longitude,
17 | Latitude = address.Location.Coordinate.Latitude,
18 | FeatureName = address.Name,
19 | PostalCode = address.PostalCode,
20 | SubLocality = address.SubLocality,
21 | CountryCode = address.IsoCountryCode,
22 | CountryName = address.Country,
23 | Thoroughfare = address.Thoroughfare,
24 | SubThoroughfare = address.SubThoroughfare,
25 | Locality = address.Locality,
26 | AdminArea = address.AdministrativeArea,
27 | SubAdminArea = address.SubAdministrativeArea
28 | });
29 | }
30 | public static DateTime ToDateTime(this NSDate date)
31 | {
32 | return (DateTime)date;
33 | }
34 | }
35 | }
--------------------------------------------------------------------------------
/src/Geolocator.Plugin/CrossGeolocator.shared.cs:
--------------------------------------------------------------------------------
1 | using Plugin.Geolocator.Abstractions;
2 | using System;
3 |
4 | namespace Plugin.Geolocator
5 | {
6 | ///
7 | /// Cross platform Geolocator implemenations
8 | ///
9 | public class CrossGeolocator
10 | {
11 | static Lazy implementation = new Lazy(() => CreateGeolocator(), System.Threading.LazyThreadSafetyMode.PublicationOnly);
12 | ///
13 | /// Gets if the plugin is supported on the current platform.
14 | ///
15 | public static bool IsSupported => implementation.Value == null ? false : true;
16 |
17 | ///
18 | /// Current plugin implementation to use
19 | ///
20 | public static IGeolocator Current
21 | {
22 | get
23 | {
24 | var ret = implementation.Value;
25 | if (ret == null)
26 | {
27 | throw NotImplementedInReferenceAssembly();
28 | }
29 | return ret;
30 | }
31 | }
32 |
33 | static IGeolocator CreateGeolocator()
34 | {
35 | #if NETSTANDARD1_0 || NETSTANDARD2_0
36 | return null;
37 | #else
38 | return new GeolocatorImplementation();
39 | #endif
40 | }
41 |
42 | internal static Exception NotImplementedInReferenceAssembly() =>
43 | new NotImplementedException("This functionality is not implemented in the portable version of this assembly. You should reference the NuGet package from your main application project in order to reference the platform-specific implementation.");
44 |
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/Geolocator.Plugin/Geolocator.Plugin.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard1.0;netstandard2.0;MonoAndroid10.0;Xamarin.iOS10;uap10.0.16299;Xamarin.TVOS10;Xamarin.Mac20
5 | Plugin.Geolocator
6 | Plugin.Geolocator
7 | $(AssemblyName) ($(TargetFramework))
8 | 1.0.0.0
9 | 1.0.0.0
10 | 1.0.0.0
11 | James Montemagno
12 | Xam.Plugin.Geolocator
13 | true
14 | https://raw.githubusercontent.com/jamesmontemagno/GeolocatorPlugin/master/art/icon.png
15 | https://github.com/jamesmontemagno/GeolocatorPlugin/blob/master/LICENSE
16 | JamesMontemagno
17 | https://github.com/jamesmontemagno/GeolocatorPlugin
18 | Easly access geolocation across Xamarin.iOS, Xamarin.Android, and Windows.
19 | xamarin, xamarin.forms, plugin, plugin for xamarin, geolocation, geocoding, ios, android, uwp
20 | Geolocator Plugin for Xamarin and Windows
21 |
22 | Easly access geolocation across Xamarin.iOS, Xamarin.Android, and Windows.
23 |
24 | Copyright 2021
25 | https://github.com/jamesmontemagno/GeolocatorPlugin
26 | See: https://github.com/jamesmontemagno/GeolocatorPlugin
27 |
28 | en
29 | default
30 | false
31 | portable
32 | $(DefineConstants);
33 |
34 |
35 |
36 | true
37 | false
38 |
39 |
40 | true
41 |
42 | true
43 |
44 | true
45 |
46 | $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
--------------------------------------------------------------------------------
/src/Geolocator.Plugin/UWP/Extensions.uwp.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.CompilerServices;
3 | using Windows.Foundation;
4 |
5 | namespace Plugin.Geolocator
6 | {
7 | internal static class Extensions
8 | {
9 | public static ConfiguredTaskAwaitable AsTask(this IAsyncOperation self, bool continueOnCapturedContext)
10 | {
11 | return self.AsTask().ConfigureAwait(continueOnCapturedContext);
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/Geolocator.Plugin/UWP/GeolocatorUtils.uwp.cs:
--------------------------------------------------------------------------------
1 | using Plugin.Geolocator.Abstractions;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using Windows.Services.Maps;
5 |
6 | namespace Plugin.Geolocator
7 | {
8 | internal static class GeolocatorUtils
9 | {
10 | internal static IEnumerable ToAddresses(this IEnumerable addresses)
11 | {
12 | return addresses.Select(address => new Address
13 | {
14 | Longitude = address.Point.Position.Longitude,
15 | Latitude = address.Point.Position.Latitude,
16 | FeatureName = address.DisplayName,
17 | PostalCode = address.Address.PostCode,
18 | CountryCode = address.Address.CountryCode,
19 | CountryName = address.Address.Country,
20 | Thoroughfare = address.Address.Street,
21 | SubThoroughfare = address.Address.StreetNumber,
22 | Locality = address.Address.Town,
23 | AdminArea = address.Address.Region,
24 | SubAdminArea = address.Address.District
25 | });
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/Geolocator.Plugin/UWP/Timeout.uwp.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading;
3 | using System.Threading.Tasks;
4 |
5 | namespace Plugin.Geolocator
6 | {
7 | internal class Timeout
8 | {
9 |
10 |
11 | public Timeout(int timeout, Action timesup)
12 | {
13 | if (timeout == Infite)
14 | return; // nothing to do
15 | if (timeout < 0)
16 | throw new ArgumentOutOfRangeException("timeoutMilliseconds");
17 | if (timesup == null)
18 | throw new ArgumentNullException("timesup");
19 |
20 | Task.Delay(TimeSpan.FromMilliseconds(timeout), canceller.Token)
21 | .ContinueWith(t =>
22 | {
23 | if (!t.IsCanceled)
24 | timesup();
25 | });
26 | }
27 |
28 | public void Cancel()
29 | {
30 | canceller.Cancel();
31 | }
32 |
33 | private readonly CancellationTokenSource canceller = new CancellationTokenSource();
34 |
35 | public const int Infite = -1;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.Droid/Assets/AboutAssets.txt:
--------------------------------------------------------------------------------
1 | Any raw assets you want to be deployed with your application can be placed in
2 | this directory (and child directories) and given a Build Action of "AndroidAsset".
3 |
4 | These files will be deployed with your package and will be accessible using Android's
5 | AssetManager, like this:
6 |
7 | public class ReadAsset : Activity
8 | {
9 | protected override void OnCreate (Bundle bundle)
10 | {
11 | base.OnCreate (bundle);
12 |
13 | InputStream input = Assets.Open ("my_asset.txt");
14 | }
15 | }
16 |
17 | Additionally, some Android functions will automatically load asset files:
18 |
19 | Typeface tf = Typeface.CreateFromAsset (Context.Assets, "fonts/samplefont.ttf");
20 |
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.Droid/GeolocatorTests.Droid.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
7 | {E9C12CE5-7691-47AE-8D1E-C0598F6C5518}
8 | Library
9 | GeolocatorTests.Droid
10 | Assets
11 | Resources
12 | Resource
13 | Resources\Resource.designer.cs
14 | True
15 | False
16 | GeolocatorTests.Droid
17 | Properties\AndroidManifest.xml
18 | v10.0
19 |
20 |
21 |
22 |
23 |
24 |
25 | true
26 | full
27 | false
28 | bin\Debug
29 | DEBUG;
30 | prompt
31 | 4
32 | None
33 | false
34 | false
35 | false
36 | false
37 | armeabi-v7a;x86;x86_64;arm64-v8a
38 |
39 |
40 | full
41 | true
42 | bin\Release
43 | prompt
44 | 4
45 | false
46 | false
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 | {36b8dd43-b679-4d13-8ba9-ded633e7b25f}
79 | Geolocator.Plugin
80 |
81 |
82 | {7D60E3CB-2799-4416-85BA-2374284EB3F1}
83 | GeolocatorTests
84 |
85 |
86 |
87 |
88 | 5.0.0.2125
89 |
90 |
91 |
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.Droid/MainActivity.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | using Android.App;
4 | using Android.Content;
5 | using Android.Content.PM;
6 | using Android.Runtime;
7 | using Android.Views;
8 | using Android.Widget;
9 | using Android.OS;
10 |
11 | namespace GeolocatorTests.Droid
12 | {
13 | [Activity(Label = "GeolocatorTests.Droid", Icon = "@drawable/icon", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
14 | public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsApplicationActivity
15 | {
16 | protected override void OnCreate(Bundle bundle)
17 | {
18 | base.OnCreate(bundle);
19 |
20 | global::Xamarin.Forms.Forms.Init(this, bundle);
21 |
22 | LoadApplication(new App());
23 | }
24 |
25 | public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
26 | {
27 | Plugin.Permissions.PermissionsImplementation.Current.OnRequestPermissionsResult(requestCode, permissions, grantResults);
28 | }
29 | }
30 | }
31 |
32 |
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.Droid/MainApplication.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | using Android.App;
4 | using Android.OS;
5 | using Android.Runtime;
6 | using Plugin.CurrentActivity;
7 |
8 | namespace GeolocatorTests.Droid
9 | {
10 | //You can specify additional application information in this attribute
11 | [Application]
12 | public class MainApplication : Application, Application.IActivityLifecycleCallbacks
13 | {
14 | public MainApplication(IntPtr handle, JniHandleOwnership transer)
15 | :base(handle, transer)
16 | {
17 | }
18 |
19 | public override void OnCreate()
20 | {
21 | base.OnCreate();
22 | RegisterActivityLifecycleCallbacks(this);
23 | //A great place to initialize Xamarin.Insights and Dependency Services!
24 | }
25 |
26 | public override void OnTerminate()
27 | {
28 | base.OnTerminate();
29 | UnregisterActivityLifecycleCallbacks(this);
30 | }
31 |
32 | public void OnActivityCreated(Activity activity, Bundle savedInstanceState)
33 | {
34 | CrossCurrentActivity.Current.Activity = activity;
35 | }
36 |
37 | public void OnActivityDestroyed(Activity activity)
38 | {
39 | }
40 |
41 | public void OnActivityPaused(Activity activity)
42 | {
43 | }
44 |
45 | public void OnActivityResumed(Activity activity)
46 | {
47 | CrossCurrentActivity.Current.Activity = activity;
48 | }
49 |
50 | public void OnActivitySaveInstanceState(Activity activity, Bundle outState)
51 | {
52 | }
53 |
54 | public void OnActivityStarted(Activity activity)
55 | {
56 | CrossCurrentActivity.Current.Activity = activity;
57 | }
58 |
59 | public void OnActivityStopped(Activity activity)
60 | {
61 | }
62 | }
63 | }
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.Droid/Properties/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.Droid/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using Android.App;
4 |
5 | // Information about this assembly is defined by the following attributes.
6 | // Change them to the values specific to your project.
7 |
8 | [assembly: AssemblyTitle("GeolocatorTests.Droid")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("")]
13 | [assembly: AssemblyCopyright("jamesmontemagno")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
18 | // The form "{Major}.{Minor}.*" will automatically update the build and revision,
19 | // and "{Major}.{Minor}.{Build}.*" will update just the revision.
20 |
21 | [assembly: AssemblyVersion("1.0.0")]
22 |
23 | // The following attributes are used to specify the signing key for the assembly,
24 | // if desired. See the Mono documentation for more information about signing.
25 |
26 | //[assembly: AssemblyDelaySign(false)]
27 | //[assembly: AssemblyKeyFile("")]
28 |
29 |
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.Droid/Resources/AboutResources.txt:
--------------------------------------------------------------------------------
1 | Images, layout descriptions, binary blobs and string dictionaries can be included
2 | in your application as resource files. Various Android APIs are designed to
3 | operate on the resource IDs instead of dealing with images, strings or binary blobs
4 | directly.
5 |
6 | For example, a sample Android app that contains a user interface layout (main.axml),
7 | an internationalization string table (strings.xml) and some icons (drawable-XXX/icon.png)
8 | would keep its resources in the "Resources" directory of the application:
9 |
10 | Resources/
11 | drawable/
12 | icon.png
13 |
14 | layout/
15 | main.axml
16 |
17 | values/
18 | strings.xml
19 |
20 | In order to get the build system to recognize Android resources, set the build action to
21 | "AndroidResource". The native Android APIs do not operate directly with filenames, but
22 | instead operate on resource IDs. When you compile an Android application that uses resources,
23 | the build system will package the resources for distribution and generate a class called "R"
24 | (this is an Android convention) that contains the tokens for each one of the resources
25 | included. For example, for the above Resources layout, this is what the R class would expose:
26 |
27 | public class R {
28 | public class drawable {
29 | public const int icon = 0x123;
30 | }
31 |
32 | public class layout {
33 | public const int main = 0x456;
34 | }
35 |
36 | public class strings {
37 | public const int first_string = 0xabc;
38 | public const int second_string = 0xbcd;
39 | }
40 | }
41 |
42 | You would then use R.drawable.icon to reference the drawable/icon.png file, or R.layout.main
43 | to reference the layout/main.axml file, or R.strings.first_string to reference the first
44 | string in the dictionary file values/strings.xml.
45 |
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.Droid/Resources/drawable-hdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jamesmontemagno/GeolocatorPlugin/f0b80019c9f127d03341bb6e191dbf58ac262580/src/Tests/GeolocatorTests.Droid/Resources/drawable-hdpi/icon.png
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.Droid/Resources/drawable-xhdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jamesmontemagno/GeolocatorPlugin/f0b80019c9f127d03341bb6e191dbf58ac262580/src/Tests/GeolocatorTests.Droid/Resources/drawable-xhdpi/icon.png
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.Droid/Resources/drawable-xxhdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jamesmontemagno/GeolocatorPlugin/f0b80019c9f127d03341bb6e191dbf58ac262580/src/Tests/GeolocatorTests.Droid/Resources/drawable-xxhdpi/icon.png
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.Droid/Resources/drawable/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jamesmontemagno/GeolocatorPlugin/f0b80019c9f127d03341bb6e191dbf58ac262580/src/Tests/GeolocatorTests.Droid/Resources/drawable/icon.png
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.Mac/AppDelegate.cs:
--------------------------------------------------------------------------------
1 | using AppKit;
2 | using Foundation;
3 |
4 | namespace GeolocatorTests.Mac
5 | {
6 | [Register("AppDelegate")]
7 | public class AppDelegate : NSApplicationDelegate
8 | {
9 | public AppDelegate()
10 | {
11 | }
12 |
13 | public override void DidFinishLaunching(NSNotification notification)
14 | {
15 | // Insert code here to initialize your application
16 | }
17 |
18 | public override void WillTerminate(NSNotification notification)
19 | {
20 | // Insert code here to tear down your application
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.Mac/Assets.xcassets/AppIcon.appiconset/AppIcon-128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jamesmontemagno/GeolocatorPlugin/f0b80019c9f127d03341bb6e191dbf58ac262580/src/Tests/GeolocatorTests.Mac/Assets.xcassets/AppIcon.appiconset/AppIcon-128.png
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.Mac/Assets.xcassets/AppIcon.appiconset/AppIcon-128@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jamesmontemagno/GeolocatorPlugin/f0b80019c9f127d03341bb6e191dbf58ac262580/src/Tests/GeolocatorTests.Mac/Assets.xcassets/AppIcon.appiconset/AppIcon-128@2x.png
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.Mac/Assets.xcassets/AppIcon.appiconset/AppIcon-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jamesmontemagno/GeolocatorPlugin/f0b80019c9f127d03341bb6e191dbf58ac262580/src/Tests/GeolocatorTests.Mac/Assets.xcassets/AppIcon.appiconset/AppIcon-16.png
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.Mac/Assets.xcassets/AppIcon.appiconset/AppIcon-16@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jamesmontemagno/GeolocatorPlugin/f0b80019c9f127d03341bb6e191dbf58ac262580/src/Tests/GeolocatorTests.Mac/Assets.xcassets/AppIcon.appiconset/AppIcon-16@2x.png
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.Mac/Assets.xcassets/AppIcon.appiconset/AppIcon-256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jamesmontemagno/GeolocatorPlugin/f0b80019c9f127d03341bb6e191dbf58ac262580/src/Tests/GeolocatorTests.Mac/Assets.xcassets/AppIcon.appiconset/AppIcon-256.png
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.Mac/Assets.xcassets/AppIcon.appiconset/AppIcon-256@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jamesmontemagno/GeolocatorPlugin/f0b80019c9f127d03341bb6e191dbf58ac262580/src/Tests/GeolocatorTests.Mac/Assets.xcassets/AppIcon.appiconset/AppIcon-256@2x.png
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.Mac/Assets.xcassets/AppIcon.appiconset/AppIcon-32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jamesmontemagno/GeolocatorPlugin/f0b80019c9f127d03341bb6e191dbf58ac262580/src/Tests/GeolocatorTests.Mac/Assets.xcassets/AppIcon.appiconset/AppIcon-32.png
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.Mac/Assets.xcassets/AppIcon.appiconset/AppIcon-32@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jamesmontemagno/GeolocatorPlugin/f0b80019c9f127d03341bb6e191dbf58ac262580/src/Tests/GeolocatorTests.Mac/Assets.xcassets/AppIcon.appiconset/AppIcon-32@2x.png
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.Mac/Assets.xcassets/AppIcon.appiconset/AppIcon-512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jamesmontemagno/GeolocatorPlugin/f0b80019c9f127d03341bb6e191dbf58ac262580/src/Tests/GeolocatorTests.Mac/Assets.xcassets/AppIcon.appiconset/AppIcon-512.png
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.Mac/Assets.xcassets/AppIcon.appiconset/AppIcon-512@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jamesmontemagno/GeolocatorPlugin/f0b80019c9f127d03341bb6e191dbf58ac262580/src/Tests/GeolocatorTests.Mac/Assets.xcassets/AppIcon.appiconset/AppIcon-512@2x.png
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.Mac/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images": [
3 | {
4 | "filename": "AppIcon-16.png",
5 | "size": "16x16",
6 | "scale": "1x",
7 | "idiom": "mac"
8 | },
9 | {
10 | "filename": "AppIcon-16@2x.png",
11 | "size": "16x16",
12 | "scale": "2x",
13 | "idiom": "mac"
14 | },
15 | {
16 | "filename": "AppIcon-32.png",
17 | "size": "32x32",
18 | "scale": "1x",
19 | "idiom": "mac"
20 | },
21 | {
22 | "filename": "AppIcon-32@2x.png",
23 | "size": "32x32",
24 | "scale": "2x",
25 | "idiom": "mac"
26 | },
27 | {
28 | "filename": "AppIcon-128.png",
29 | "size": "128x128",
30 | "scale": "1x",
31 | "idiom": "mac"
32 | },
33 | {
34 | "filename": "AppIcon-128@2x.png",
35 | "size": "128x128",
36 | "scale": "2x",
37 | "idiom": "mac"
38 | },
39 | {
40 | "filename": "AppIcon-256.png",
41 | "size": "256x256",
42 | "scale": "1x",
43 | "idiom": "mac"
44 | },
45 | {
46 | "filename": "AppIcon-256@2x.png",
47 | "size": "256x256",
48 | "scale": "2x",
49 | "idiom": "mac"
50 | },
51 | {
52 | "filename": "AppIcon-512.png",
53 | "size": "512x512",
54 | "scale": "1x",
55 | "idiom": "mac"
56 | },
57 | {
58 | "filename": "AppIcon-512@2x.png",
59 | "size": "512x512",
60 | "scale": "2x",
61 | "idiom": "mac"
62 | }
63 | ],
64 | "info": {
65 | "version": 1,
66 | "author": "xcode"
67 | }
68 | }
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.Mac/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.Mac/Entitlements.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.Mac/GeolocatorTests.Mac.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | {716095F1-D4B9-4C76-A2E5-395BDE971C67}
7 | {A3F8F2AB-B479-4A4A-A458-A89E7DC349F1};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
8 | Exe
9 | GeolocatorTests.Mac
10 | GeolocatorTests.Mac
11 | v2.0
12 | Xamarin.Mac
13 | Resources
14 |
15 |
16 | true
17 | full
18 | false
19 | bin\Debug
20 | DEBUG;
21 | prompt
22 | 4
23 | false
24 | Mac Developer
25 | false
26 | false
27 | false
28 | true
29 | true
30 | true
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 | pdbonly
42 | true
43 | bin\Release
44 |
45 |
46 | prompt
47 | 4
48 | false
49 | true
50 | false
51 | true
52 | true
53 | true
54 | SdkOnly
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 | ViewController.cs
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 | {36b8dd43-b679-4d13-8ba9-ded633e7b25f}
102 | Geolocator.Plugin
103 |
104 |
105 |
106 |
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.Mac/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleName
6 | GeolocatorTests.Mac
7 | CFBundleIdentifier
8 | com.refractored.geolocatortests-mac
9 | CFBundleShortVersionString
10 | 1.0
11 | CFBundleVersion
12 | 1
13 | LSMinimumSystemVersion
14 | 10.12
15 | CFBundleDevelopmentRegion
16 | en
17 | CFBundleInfoDictionaryVersion
18 | 6.0
19 | CFBundlePackageType
20 | APPL
21 | CFBundleSignature
22 | ????
23 | NSHumanReadableCopyright
24 | (c) James Montemagno
25 | NSPrincipalClass
26 | NSApplication
27 | NSMainStoryboardFile
28 | Main
29 | XSAppIconAssets
30 | Assets.xcassets/AppIcon.appiconset
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.Mac/Main.cs:
--------------------------------------------------------------------------------
1 | using AppKit;
2 |
3 | namespace GeolocatorTests.Mac
4 | {
5 | static class MainClass
6 | {
7 | static void Main(string[] args)
8 | {
9 | NSApplication.Init();
10 | NSApplication.Main(args);
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.Mac/ViewController.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using AppKit;
4 | using Foundation;
5 | using Plugin.Geolocator;
6 |
7 | namespace GeolocatorTests.Mac
8 | {
9 | public partial class ViewController : NSViewController
10 | {
11 | public ViewController(IntPtr handle) : base(handle)
12 | {
13 | }
14 |
15 | public override void ViewDidLoad()
16 | {
17 | base.ViewDidLoad();
18 |
19 |
20 |
21 | // Do any additional setup after loading the view.
22 | }
23 |
24 | partial void ButtonAvailableClicked(NSObject sender)
25 | {
26 | LabelIsAvailable.StringValue = CrossGeolocator.Current.IsGeolocationAvailable ? "Available" : "Not Available";
27 | }
28 |
29 | partial void ButtonEnabledClicked(NSObject sender)
30 | {
31 | LabelIsEnabled.StringValue = CrossGeolocator.Current.IsGeolocationEnabled ? "Enabled" : "Not Enabled";
32 |
33 | }
34 |
35 | async partial void ButtonGetAddressClicked(NSObject sender)
36 | {
37 | try
38 | {
39 | var position = await CrossGeolocator.Current.GetPositionAsync(TimeSpan.FromSeconds(15));
40 | var address = await CrossGeolocator.Current.GetAddressesForPositionAsync(position);
41 |
42 | var first = address.FirstOrDefault();
43 | LabelPosition.StringValue = $"Address: {first.Thoroughfare} {first.Locality}";
44 | }
45 | catch (Exception ex)
46 | {
47 | LabelPosition.StringValue = "Error";
48 | }
49 | }
50 |
51 | async partial void ButtonGetLocationClicked(NSObject sender)
52 | {
53 | var test = await CrossGeolocator.Current.GetPositionAsync(TimeSpan.FromMinutes(2));
54 | LabelPosition.StringValue = "Full: Lat: " + (test.Latitude).ToString() + " Long: " + (test.Longitude).ToString();
55 | LabelPosition.StringValue += "\n" + $"Time: {test.Timestamp.ToString()}";
56 | LabelPosition.StringValue += "\n" + $"Heading: {test.Heading.ToString()}";
57 | LabelPosition.StringValue += "\n" + $"Speed: {test.Speed.ToString()}";
58 | LabelPosition.StringValue += "\n" + $"Accuracy: {test.Accuracy.ToString()}";
59 | LabelPosition.StringValue += "\n" + $"Altitude: {test.Altitude.ToString()}";
60 | LabelPosition.StringValue += "\n" + $"AltitudeAccuracy: {test.AltitudeAccuracy.ToString()}";
61 | }
62 |
63 | partial void ButtonListenClicked(NSObject sender)
64 | {
65 |
66 | }
67 |
68 | public override NSObject RepresentedObject
69 | {
70 | get
71 | {
72 | return base.RepresentedObject;
73 | }
74 | set
75 | {
76 | base.RepresentedObject = value;
77 | // Update the view, if already loaded.
78 | }
79 | }
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.Mac/ViewController.designer.cs:
--------------------------------------------------------------------------------
1 | // WARNING
2 | //
3 | // This file has been generated automatically by Xamarin Studio to store outlets and
4 | // actions made in the UI designer. If it is removed, they will be lost.
5 | // Manual changes to this file may not be handled correctly.
6 | //
7 | using Foundation;
8 | using System.CodeDom.Compiler;
9 |
10 | namespace GeolocatorTests.Mac
11 | {
12 | [Register ("ViewController")]
13 | partial class ViewController
14 | {
15 | [Outlet]
16 | AppKit.NSButton ButtonGetAddress { get; set; }
17 |
18 | [Outlet]
19 | AppKit.NSButton ButtonGetLocation { get; set; }
20 |
21 | [Outlet]
22 | AppKit.NSButton ButtonIsAvailable { get; set; }
23 |
24 | [Outlet]
25 | AppKit.NSButton ButtonIsEnabled { get; set; }
26 |
27 | [Outlet]
28 | AppKit.NSButton ButtonListen { get; set; }
29 |
30 | [Outlet]
31 | AppKit.NSTextField LabelIsAvailable { get; set; }
32 |
33 | [Outlet]
34 | AppKit.NSTextField LabelIsEnabled { get; set; }
35 |
36 | [Outlet]
37 | AppKit.NSTextField LabelListenPosition { get; set; }
38 |
39 | [Outlet]
40 | AppKit.NSTextField LabelPosition { get; set; }
41 |
42 | [Action ("ButtonAvailableClicked:")]
43 | partial void ButtonAvailableClicked (Foundation.NSObject sender);
44 |
45 | [Action ("ButtonEnabledClicked:")]
46 | partial void ButtonEnabledClicked (Foundation.NSObject sender);
47 |
48 | [Action ("ButtonGetAddressClicked:")]
49 | partial void ButtonGetAddressClicked (Foundation.NSObject sender);
50 |
51 | [Action ("ButtonGetLocationClicked:")]
52 | partial void ButtonGetLocationClicked (Foundation.NSObject sender);
53 |
54 | [Action ("ButtonListenClicked:")]
55 | partial void ButtonListenClicked (Foundation.NSObject sender);
56 |
57 | void ReleaseDesignerOutlets ()
58 | {
59 | if (ButtonIsAvailable != null) {
60 | ButtonIsAvailable.Dispose ();
61 | ButtonIsAvailable = null;
62 | }
63 |
64 | if (ButtonIsEnabled != null) {
65 | ButtonIsEnabled.Dispose ();
66 | ButtonIsEnabled = null;
67 | }
68 |
69 | if (ButtonGetLocation != null) {
70 | ButtonGetLocation.Dispose ();
71 | ButtonGetLocation = null;
72 | }
73 |
74 | if (ButtonGetAddress != null) {
75 | ButtonGetAddress.Dispose ();
76 | ButtonGetAddress = null;
77 | }
78 |
79 | if (ButtonListen != null) {
80 | ButtonListen.Dispose ();
81 | ButtonListen = null;
82 | }
83 |
84 | if (LabelIsAvailable != null) {
85 | LabelIsAvailable.Dispose ();
86 | LabelIsAvailable = null;
87 | }
88 |
89 | if (LabelIsEnabled != null) {
90 | LabelIsEnabled.Dispose ();
91 | LabelIsEnabled = null;
92 | }
93 |
94 | if (LabelPosition != null) {
95 | LabelPosition.Dispose ();
96 | LabelPosition = null;
97 | }
98 |
99 | if (LabelListenPosition != null) {
100 | LabelListenPosition.Dispose ();
101 | LabelListenPosition = null;
102 | }
103 | }
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.UWP/App.xaml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.UWP/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Runtime.InteropServices.WindowsRuntime;
6 | using Windows.ApplicationModel;
7 | using Windows.ApplicationModel.Activation;
8 | using Windows.Foundation;
9 | using Windows.Foundation.Collections;
10 | using Windows.UI.Xaml;
11 | using Windows.UI.Xaml.Controls;
12 | using Windows.UI.Xaml.Controls.Primitives;
13 | using Windows.UI.Xaml.Data;
14 | using Windows.UI.Xaml.Input;
15 | using Windows.UI.Xaml.Media;
16 | using Windows.UI.Xaml.Navigation;
17 |
18 | namespace GeolocatorTests.UWP
19 | {
20 | ///
21 | /// Provides application-specific behavior to supplement the default Application class.
22 | ///
23 | sealed partial class App : Application
24 | {
25 | ///
26 | /// Initializes the singleton application object. This is the first line of authored code
27 | /// executed, and as such is the logical equivalent of main() or WinMain().
28 | ///
29 | public App()
30 | {
31 | this.InitializeComponent();
32 | this.Suspending += OnSuspending;
33 | }
34 |
35 | ///
36 | /// Invoked when the application is launched normally by the end user. Other entry points
37 | /// will be used such as when the application is launched to open a specific file.
38 | ///
39 | /// Details about the launch request and process.
40 | protected override void OnLaunched(LaunchActivatedEventArgs e)
41 | {
42 | Frame rootFrame = Window.Current.Content as Frame;
43 |
44 | // Do not repeat app initialization when the Window already has content,
45 | // just ensure that the window is active
46 | if (rootFrame == null)
47 | {
48 | // Create a Frame to act as the navigation context and navigate to the first page
49 | rootFrame = new Frame();
50 |
51 | rootFrame.NavigationFailed += OnNavigationFailed;
52 | Xamarin.Forms.Forms.Init(e); // requires the `e` parameter
53 |
54 | if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
55 | {
56 | //TODO: Load state from previously suspended application
57 | }
58 |
59 | // Place the frame in the current Window
60 | Window.Current.Content = rootFrame;
61 | }
62 |
63 | if (e.PrelaunchActivated == false)
64 | {
65 | if (rootFrame.Content == null)
66 | {
67 | // When the navigation stack isn't restored navigate to the first page,
68 | // configuring the new page by passing required information as a navigation
69 | // parameter
70 | rootFrame.Navigate(typeof(MainPage), e.Arguments);
71 | }
72 | // Ensure the current window is active
73 | Window.Current.Activate();
74 | }
75 | }
76 |
77 | ///
78 | /// Invoked when Navigation to a certain page fails
79 | ///
80 | /// The Frame which failed navigation
81 | /// Details about the navigation failure
82 | void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
83 | {
84 | throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
85 | }
86 |
87 | ///
88 | /// Invoked when application execution is being suspended. Application state is saved
89 | /// without knowing whether the application will be terminated or resumed with the contents
90 | /// of memory still intact.
91 | ///
92 | /// The source of the suspend request.
93 | /// Details about the suspend request.
94 | private void OnSuspending(object sender, SuspendingEventArgs e)
95 | {
96 | var deferral = e.SuspendingOperation.GetDeferral();
97 | //TODO: Save application state and stop any background activity
98 | deferral.Complete();
99 | }
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.UWP/Assets/LockScreenLogo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jamesmontemagno/GeolocatorPlugin/f0b80019c9f127d03341bb6e191dbf58ac262580/src/Tests/GeolocatorTests.UWP/Assets/LockScreenLogo.scale-200.png
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.UWP/Assets/SplashScreen.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jamesmontemagno/GeolocatorPlugin/f0b80019c9f127d03341bb6e191dbf58ac262580/src/Tests/GeolocatorTests.UWP/Assets/SplashScreen.scale-200.png
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.UWP/Assets/Square150x150Logo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jamesmontemagno/GeolocatorPlugin/f0b80019c9f127d03341bb6e191dbf58ac262580/src/Tests/GeolocatorTests.UWP/Assets/Square150x150Logo.scale-200.png
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.UWP/Assets/Square44x44Logo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jamesmontemagno/GeolocatorPlugin/f0b80019c9f127d03341bb6e191dbf58ac262580/src/Tests/GeolocatorTests.UWP/Assets/Square44x44Logo.scale-200.png
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.UWP/Assets/Square44x44Logo.targetsize-24_altform-unplated.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jamesmontemagno/GeolocatorPlugin/f0b80019c9f127d03341bb6e191dbf58ac262580/src/Tests/GeolocatorTests.UWP/Assets/Square44x44Logo.targetsize-24_altform-unplated.png
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.UWP/Assets/StoreLogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jamesmontemagno/GeolocatorPlugin/f0b80019c9f127d03341bb6e191dbf58ac262580/src/Tests/GeolocatorTests.UWP/Assets/StoreLogo.png
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.UWP/Assets/Wide310x150Logo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jamesmontemagno/GeolocatorPlugin/f0b80019c9f127d03341bb6e191dbf58ac262580/src/Tests/GeolocatorTests.UWP/Assets/Wide310x150Logo.scale-200.png
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.UWP/MainPage.xaml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.UWP/MainPage.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Runtime.InteropServices.WindowsRuntime;
6 | using Windows.Foundation;
7 | using Windows.Foundation.Collections;
8 | using Windows.UI.Xaml;
9 | using Windows.UI.Xaml.Controls;
10 | using Windows.UI.Xaml.Controls.Primitives;
11 | using Windows.UI.Xaml.Data;
12 | using Windows.UI.Xaml.Input;
13 | using Windows.UI.Xaml.Media;
14 | using Windows.UI.Xaml.Navigation;
15 |
16 | // The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409
17 |
18 | namespace GeolocatorTests.UWP
19 | {
20 | ///
21 | /// An empty page that can be used on its own or navigated to within a Frame.
22 | ///
23 | public sealed partial class MainPage
24 | {
25 | public MainPage()
26 | {
27 | this.InitializeComponent();
28 | LoadApplication(new GeolocatorTests.App());
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.UWP/Package.appxmanifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | GeolocatorTests.UWP
7 | Motz
8 | Assets\StoreLogo.png
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.UWP/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("GeolocatorTests.UWP")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("GeolocatorTests.UWP")]
13 | [assembly: AssemblyCopyright("Copyright © 2017")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Version information for an assembly consists of the following four values:
18 | //
19 | // Major Version
20 | // Minor Version
21 | // Build Number
22 | // Revision
23 | //
24 | // You can specify all the values or you can default the Build and Revision Numbers
25 | // by using the '*' as shown below:
26 | // [assembly: AssemblyVersion("1.0.*")]
27 | [assembly: AssemblyVersion("1.0.0.0")]
28 | [assembly: AssemblyFileVersion("1.0.0.0")]
29 | [assembly: ComVisible(false)]
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.UWP/Properties/Default.rd.xml:
--------------------------------------------------------------------------------
1 |
17 |
18 |
19 |
20 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.iOS/AppDelegate.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 |
5 | using Foundation;
6 | using UIKit;
7 |
8 | namespace GeolocatorTests.iOS
9 | {
10 | [Register("AppDelegate")]
11 | public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
12 | {
13 | public override bool FinishedLaunching(UIApplication app, NSDictionary options)
14 | {
15 | global::Xamarin.Forms.Forms.Init();
16 |
17 | LoadApplication(new App());
18 |
19 | return base.FinishedLaunching(app, options);
20 | }
21 | }
22 | }
23 |
24 |
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.iOS/Entitlements.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.iOS/GeolocatorTests.iOS.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | iPhoneSimulator
6 | {FEACFBD2-3405-455C-9665-78FE426C6842};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
7 | {5F010020-BEE6-47EE-A4CE-6A8C42B9CB29}
8 | Exe
9 | GeolocatorTests.iOS
10 | Resources
11 | GeolocatorTestsiOS
12 |
13 |
14 |
15 |
16 | true
17 | full
18 | false
19 | bin\iPhoneSimulator\Debug
20 | DEBUG;ENABLE_TEST_CLOUD;
21 | prompt
22 | 4
23 | false
24 | i386, x86_64
25 | None
26 | true
27 | true
28 | true
29 | true
30 | iPhone Developer
31 | true
32 | true
33 |
34 |
35 | full
36 | true
37 | bin\iPhone\Release
38 | prompt
39 | 4
40 | false
41 | ARMv7, ARM64
42 | Entitlements.plist
43 | true
44 | true
45 | iPhone Developer
46 | true
47 |
48 |
49 | full
50 | true
51 | bin\iPhoneSimulator\Release
52 | prompt
53 | 4
54 | false
55 | i386
56 | None
57 | true
58 | iPhone Developer
59 | true
60 |
61 |
62 | true
63 | full
64 | false
65 | bin\iPhone\Debug
66 | DEBUG;ENABLE_TEST_CLOUD;
67 | prompt
68 | 4
69 | false
70 | ARMv7s, ARM64
71 | Entitlements.plist
72 | true
73 | iPhone Developer
74 | true
75 | true
76 | true
77 | true
78 | true
79 |
80 |
81 |
82 | false
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 | Designer
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 | {36b8dd43-b679-4d13-8ba9-ded633e7b25f}
102 | Geolocator.Plugin
103 |
104 |
105 | {7D60E3CB-2799-4416-85BA-2374284EB3F1}
106 | GeolocatorTests
107 |
108 |
109 |
110 |
111 | 5.0.0.2125
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.iOS/GeolocatorTests.iOS.csproj.bak:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | iPhoneSimulator
6 | {FEACFBD2-3405-455C-9665-78FE426C6842};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
7 | {5F010020-BEE6-47EE-A4CE-6A8C42B9CB29}
8 | Exe
9 | GeolocatorTests.iOS
10 | Resources
11 | GeolocatorTests.iOS
12 |
13 |
14 | true
15 | full
16 | false
17 | bin\iPhoneSimulator\Debug
18 | DEBUG;ENABLE_TEST_CLOUD;
19 | prompt
20 | 4
21 | false
22 | i386
23 | None
24 | true
25 | true
26 | true
27 | true
28 | iPhone Developer
29 | true
30 |
31 |
32 | full
33 | true
34 | bin\iPhone\Release
35 | prompt
36 | 4
37 | false
38 | ARMv7, ARM64
39 | Entitlements.plist
40 | true
41 | true
42 | iPhone Developer
43 | true
44 |
45 |
46 | full
47 | true
48 | bin\iPhoneSimulator\Release
49 | prompt
50 | 4
51 | false
52 | i386
53 | None
54 | true
55 | iPhone Developer
56 | true
57 |
58 |
59 | true
60 | full
61 | false
62 | bin\iPhone\Debug
63 | DEBUG;ENABLE_TEST_CLOUD;
64 | prompt
65 | 4
66 | false
67 | ARMv7, ARM64
68 | Entitlements.plist
69 | true
70 | iPhone Developer
71 | true
72 | true
73 | true
74 | true
75 | true
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 | ..\packages\Xamarin.Forms.2.3.3.180\lib\Xamarin.iOS10\Xamarin.Forms.Platform.iOS.dll
84 |
85 |
86 | ..\packages\Xamarin.Forms.2.3.3.180\lib\Xamarin.iOS10\Xamarin.Forms.Core.dll
87 |
88 |
89 | ..\packages\Xamarin.Forms.2.3.3.180\lib\Xamarin.iOS10\Xamarin.Forms.Xaml.dll
90 |
91 |
92 | ..\packages\Xamarin.Forms.2.3.3.180\lib\Xamarin.iOS10\Xamarin.Forms.Platform.dll
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 | {7D60E3CB-2799-4416-85BA-2374284EB3F1}
115 | GeolocatorTests
116 |
117 |
118 | {2882AEEB-D4CD-4EB9-8A6C-6653B33681F0}
119 | Geolocator.Plugin.iOSUnified
120 |
121 |
122 | {6EDB0588-FFC5-4EF5-8A99-9E241D0F878D}
123 | Geolocator.Plugin.Abstractions
124 |
125 |
126 |
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.iOS/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDisplayName
6 | GeolocatorTests
7 | CFBundleIdentifier
8 | com.plugin.geolocatortests
9 | CFBundleShortVersionString
10 | 1.0
11 | CFBundleVersion
12 | 1.0
13 | LSRequiresIPhoneOS
14 |
15 | MinimumOSVersion
16 | 10.0
17 | UIDeviceFamily
18 |
19 | 1
20 | 2
21 |
22 | UILaunchStoryboardName
23 | LaunchScreen
24 | UIRequiredDeviceCapabilities
25 |
26 | armv7
27 |
28 | UISupportedInterfaceOrientations
29 |
30 | UIInterfaceOrientationPortrait
31 | UIInterfaceOrientationLandscapeLeft
32 | UIInterfaceOrientationLandscapeRight
33 |
34 | UISupportedInterfaceOrientations~ipad
35 |
36 | UIInterfaceOrientationPortrait
37 | UIInterfaceOrientationPortraitUpsideDown
38 | UIInterfaceOrientationLandscapeLeft
39 | UIInterfaceOrientationLandscapeRight
40 |
41 | XSAppIconAssets
42 | Resources/Images.xcassets/AppIcons.appiconset
43 | NSLocationWhenInUseUsageDescription
44 | Need location when in use
45 | NSLocationAlwaysAndWhenInUseUsageDescription
46 | Always and when in use!
47 | NSLocationUsageDescription
48 | Older devices need location.
49 | NSLocationAlwaysUsageDescription
50 | Can I haz location always?
51 | UIBackgroundModes
52 |
53 | location
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.iOS/Main.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 |
5 | using Foundation;
6 | using UIKit;
7 |
8 | namespace GeolocatorTests.iOS
9 | {
10 | public class Application
11 | {
12 | // This is the main entry point of the application.
13 | static void Main(string[] args)
14 | {
15 | // if you want to use a different Application Delegate class from "AppDelegate"
16 | // you can specify it here.
17 | UIApplication.Main(args, null, "AppDelegate");
18 | }
19 | }
20 | }
21 |
22 |
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.iOS/Resources/Images.xcassets/AppIcons.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images": [
3 | {
4 | "size": "29x29",
5 | "scale": "1x",
6 | "idiom": "iphone"
7 | },
8 | {
9 | "size": "29x29",
10 | "scale": "2x",
11 | "idiom": "iphone"
12 | },
13 | {
14 | "size": "29x29",
15 | "scale": "3x",
16 | "idiom": "iphone"
17 | },
18 | {
19 | "size": "40x40",
20 | "scale": "2x",
21 | "idiom": "iphone"
22 | },
23 | {
24 | "size": "40x40",
25 | "scale": "3x",
26 | "idiom": "iphone"
27 | },
28 | {
29 | "size": "57x57",
30 | "scale": "1x",
31 | "idiom": "iphone"
32 | },
33 | {
34 | "size": "57x57",
35 | "scale": "2x",
36 | "idiom": "iphone"
37 | },
38 | {
39 | "size": "60x60",
40 | "scale": "2x",
41 | "idiom": "iphone"
42 | },
43 | {
44 | "size": "60x60",
45 | "scale": "3x",
46 | "idiom": "iphone"
47 | },
48 | {
49 | "size": "29x29",
50 | "scale": "1x",
51 | "idiom": "ipad"
52 | },
53 | {
54 | "size": "29x29",
55 | "scale": "2x",
56 | "idiom": "ipad"
57 | },
58 | {
59 | "size": "40x40",
60 | "scale": "1x",
61 | "idiom": "ipad"
62 | },
63 | {
64 | "size": "40x40",
65 | "scale": "2x",
66 | "idiom": "ipad"
67 | },
68 | {
69 | "size": "50x50",
70 | "scale": "1x",
71 | "idiom": "ipad"
72 | },
73 | {
74 | "size": "50x50",
75 | "scale": "2x",
76 | "idiom": "ipad"
77 | },
78 | {
79 | "size": "72x72",
80 | "scale": "1x",
81 | "idiom": "ipad"
82 | },
83 | {
84 | "size": "72x72",
85 | "scale": "2x",
86 | "idiom": "ipad"
87 | },
88 | {
89 | "size": "76x76",
90 | "scale": "1x",
91 | "idiom": "ipad"
92 | },
93 | {
94 | "size": "76x76",
95 | "scale": "2x",
96 | "idiom": "ipad"
97 | },
98 | {
99 | "size": "120x120",
100 | "scale": "1x",
101 | "idiom": "car"
102 | }
103 | ],
104 | "info": {
105 | "version": 1,
106 | "author": "xcode"
107 | }
108 | }
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.iOS/Resources/LaunchScreen.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
21 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.tvOS/AppDelegate.cs:
--------------------------------------------------------------------------------
1 | using Foundation;
2 | using UIKit;
3 |
4 | namespace GeolocatorTests.tvOS
5 | {
6 | // The UIApplicationDelegate for the application. This class is responsible for launching the
7 | // User Interface of the application, as well as listening (and optionally responding) to application events from iOS.
8 | [Register("AppDelegate")]
9 | public class AppDelegate : UIApplicationDelegate
10 | {
11 | // class-level declarations
12 |
13 | public override UIWindow Window
14 | {
15 | get;
16 | set;
17 | }
18 |
19 | public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
20 | {
21 | // Override point for customization after application launch.
22 | // If not required for your application you can safely delete this method
23 |
24 | return true;
25 | }
26 |
27 | public override void OnResignActivation(UIApplication application)
28 | {
29 | // Invoked when the application is about to move from active to inactive state.
30 | // This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message)
31 | // or when the user quits the application and it begins the transition to the background state.
32 | // Games should use this method to pause the game.
33 | }
34 |
35 | public override void DidEnterBackground(UIApplication application)
36 | {
37 | // Use this method to release shared resources, save user data, invalidate timers and store the application state.
38 | // If your application supports background exection this method is called instead of WillTerminate when the user quits.
39 | }
40 |
41 | public override void WillEnterForeground(UIApplication application)
42 | {
43 | // Called as part of the transiton from background to active state.
44 | // Here you can undo many of the changes made on entering the background.
45 | }
46 |
47 | public override void OnActivated(UIApplication application)
48 | {
49 | // Restart any tasks that were paused (or not yet started) while the application was inactive.
50 | // If the application was previously in the background, optionally refresh the user interface.
51 | }
52 |
53 | public override void WillTerminate(UIApplication application)
54 | {
55 | // Called when the application is about to terminate. Save data, if needed. See also DidEnterBackground.
56 | }
57 | }
58 | }
59 |
60 |
61 |
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.tvOS/Entitlements.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.tvOS/GettingStarted.Xamarin:
--------------------------------------------------------------------------------
1 |
2 | GS\iOS\CS\iOSApp\GettingStarted.html
3 | false
4 |
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.tvOS/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDisplayName
6 | GeolocatorTests.tvOS
7 | CFBundleName
8 | GeolocatorTests.tvOS
9 | CFBundleIdentifier
10 | com.companyname.GeolocatorTests.tvOS
11 | CFBundleShortVersionString
12 | 1.0
13 | CFBundleVersion
14 | 1.0
15 | MinimumOSVersion
16 | 9.0
17 | UIDeviceFamily
18 |
19 | 3
20 |
21 | UIRequiredDeviceCapabilities
22 |
23 | arm64
24 |
25 | UIMainStoryboardFile
26 | Main
27 | NSLocationWhenInUseUsageDescription
28 | Need Location
29 |
30 |
31 |
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.tvOS/Main.cs:
--------------------------------------------------------------------------------
1 | using UIKit;
2 |
3 | namespace GeolocatorTests.tvOS
4 | {
5 | public class Application
6 | {
7 | // This is the main entry point of the application.
8 | static void Main(string[] args)
9 | {
10 | // if you want to use a different Application Delegate class from "AppDelegate"
11 | // you can specify it here.
12 | UIApplication.Main(args, null, "AppDelegate");
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.tvOS/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Back.imagestacklayer/Content.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "tv",
5 | "scale" : "1x"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.tvOS/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Back.imagestacklayer/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.tvOS/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "layers" : [
3 | {
4 | "filename" : "Front.imagestacklayer"
5 | },
6 | {
7 | "filename" : "Middle.imagestacklayer"
8 | },
9 | {
10 | "filename" : "Back.imagestacklayer"
11 | }
12 | ],
13 | "info" : {
14 | "version" : 1,
15 | "author" : "xcode"
16 | }
17 | }
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.tvOS/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Front.imagestacklayer/Content.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "tv",
5 | "scale" : "1x"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.tvOS/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Front.imagestacklayer/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.tvOS/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "tv",
5 | "scale" : "1x"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.tvOS/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Middle.imagestacklayer/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.tvOS/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Back.imagestacklayer/Content.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "tv",
5 | "scale" : "1x"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.tvOS/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Back.imagestacklayer/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.tvOS/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "layers" : [
3 | {
4 | "filename" : "Front.imagestacklayer"
5 | },
6 | {
7 | "filename" : "Middle.imagestacklayer"
8 | },
9 | {
10 | "filename" : "Back.imagestacklayer"
11 | }
12 | ],
13 | "info" : {
14 | "version" : 1,
15 | "author" : "xcode"
16 | }
17 | }
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.tvOS/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Front.imagestacklayer/Content.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "tv",
5 | "scale" : "1x"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.tvOS/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Front.imagestacklayer/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.tvOS/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "tv",
5 | "scale" : "1x"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.tvOS/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Middle.imagestacklayer/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.tvOS/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "assets" : [
3 | {
4 | "size" : "1280x768",
5 | "idiom" : "tv",
6 | "filename" : "App Icon - Large.imagestack",
7 | "role" : "primary-app-icon"
8 | },
9 | {
10 | "size": "400x240",
11 | "idiom": "tv",
12 | "filename": "App Icon - Small.imagestack",
13 | "role": "primary-app-icon"
14 | },
15 | {
16 | "size" : "2320x720",
17 | "idiom" : "tv",
18 | "filename" : "Top Shelf Image Wide.imageset",
19 | "role" : "top-shelf-image-wide"
20 | },
21 | {
22 | "size" : "1920x720",
23 | "idiom" : "tv",
24 | "filename" : "Top Shelf Image.imageset",
25 | "role" : "top-shelf-image"
26 | }
27 | ],
28 | "info" : {
29 | "version" : 1,
30 | "author" : "xcode"
31 | }
32 | }
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.tvOS/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image Wide.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "tv",
5 | "scale" : "1x"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.tvOS/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "tv",
5 | "scale" : "1x"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.tvOS/ViewController.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using Foundation;
4 | using Plugin.Geolocator;
5 | using UIKit;
6 |
7 | namespace GeolocatorTests.tvOS
8 | {
9 | public partial class ViewController : UIViewController
10 | {
11 | public ViewController(IntPtr handle) : base(handle)
12 | {
13 | }
14 |
15 | public override void ViewDidLoad()
16 | {
17 | base.ViewDidLoad();
18 |
19 | ButtonAddress.AllEvents += async (sender, e) =>
20 | {
21 | try
22 | {
23 | var position = await CrossGeolocator.Current.GetPositionAsync(TimeSpan.FromSeconds(15));
24 | var address = await CrossGeolocator.Current.GetAddressesForPositionAsync(position);
25 |
26 | var first = address.FirstOrDefault();
27 | LabelAddress.Text = $"Address: {first.Thoroughfare} {first.Locality}";
28 | }
29 | catch (Exception ex)
30 | {
31 | LabelAddress.Text = "Error";
32 | }
33 | };
34 |
35 |
36 | ButtonEnabled.AllEvents += async (sender, e) =>
37 | {
38 | LabelEnabled.Text = CrossGeolocator.Current.IsGeolocationEnabled ? "Enabled" : "Not Enabled";
39 |
40 | };
41 |
42 | ButtonAvailable.AllEvents += async (sender, e) =>
43 | {
44 | LabelAvailable.Text = CrossGeolocator.Current.IsGeolocationAvailable ? "Available" : "Not Available";
45 |
46 | };
47 |
48 | ButtonGetLocation.AllEvents += async (sender, e) =>
49 | {
50 | var test = await CrossGeolocator.Current.GetPositionAsync(TimeSpan.FromMinutes(2));
51 | LabelLocation.Text = "Full: Lat: " + (test.Latitude).ToString() + " Long: " + (test.Longitude).ToString();
52 | LabelLocation.Text += "\n" + $"Time: {test.Timestamp.ToString()}";
53 | LabelLocation.Text += "\n" + $"Heading: {test.Heading.ToString()}";
54 | LabelLocation.Text += "\n" + $"Speed: {test.Speed.ToString()}";
55 | LabelLocation.Text += "\n" + $"Accuracy: {test.Accuracy.ToString()}";
56 | LabelLocation.Text += "\n" + $"Altitude: {test.Altitude.ToString()}";
57 | LabelLocation.Text += "\n" + $"AltitudeAccuracy: {test.AltitudeAccuracy.ToString()}";
58 |
59 | };
60 | // Perform any additional setup after loading the view, typically from a nib.
61 | }
62 |
63 | public override void DidReceiveMemoryWarning()
64 | {
65 | base.DidReceiveMemoryWarning();
66 | // Release any cached data, images, etc that aren't in use.
67 | }
68 |
69 |
70 | }
71 | }
72 |
73 |
74 |
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests.tvOS/ViewController.designer.cs:
--------------------------------------------------------------------------------
1 | // WARNING
2 | //
3 | // This file has been generated automatically by Xamarin Studio from the outlets and
4 | // actions declared in your storyboard file.
5 | // Manual changes to this file will not be maintained.
6 | //
7 | using Foundation;
8 | using System;
9 | using System.CodeDom.Compiler;
10 |
11 | namespace GeolocatorTests.tvOS
12 | {
13 | [Register ("ViewController")]
14 | partial class ViewController
15 | {
16 | [Outlet]
17 | [GeneratedCode ("iOS Designer", "1.0")]
18 | UIKit.UIButton ButtonAddress { get; set; }
19 |
20 | [Outlet]
21 | [GeneratedCode ("iOS Designer", "1.0")]
22 | UIKit.UIButton ButtonAvailable { get; set; }
23 |
24 | [Outlet]
25 | [GeneratedCode ("iOS Designer", "1.0")]
26 | UIKit.UIButton ButtonEnabled { get; set; }
27 |
28 | [Outlet]
29 | [GeneratedCode ("iOS Designer", "1.0")]
30 | UIKit.UIButton ButtonGetLocation { get; set; }
31 |
32 | [Outlet]
33 | [GeneratedCode ("iOS Designer", "1.0")]
34 | UIKit.UILabel LabelAddress { get; set; }
35 |
36 | [Outlet]
37 | [GeneratedCode ("iOS Designer", "1.0")]
38 | UIKit.UILabel LabelAvailable { get; set; }
39 |
40 | [Outlet]
41 | [GeneratedCode ("iOS Designer", "1.0")]
42 | UIKit.UILabel LabelEnabled { get; set; }
43 |
44 | [Outlet]
45 | [GeneratedCode ("iOS Designer", "1.0")]
46 | UIKit.UILabel LabelLocation { get; set; }
47 |
48 | void ReleaseDesignerOutlets ()
49 | {
50 | if (ButtonAddress != null) {
51 | ButtonAddress.Dispose ();
52 | ButtonAddress = null;
53 | }
54 |
55 | if (ButtonAvailable != null) {
56 | ButtonAvailable.Dispose ();
57 | ButtonAvailable = null;
58 | }
59 |
60 | if (ButtonEnabled != null) {
61 | ButtonEnabled.Dispose ();
62 | ButtonEnabled = null;
63 | }
64 |
65 | if (ButtonGetLocation != null) {
66 | ButtonGetLocation.Dispose ();
67 | ButtonGetLocation = null;
68 | }
69 |
70 | if (LabelAddress != null) {
71 | LabelAddress.Dispose ();
72 | LabelAddress = null;
73 | }
74 |
75 | if (LabelAvailable != null) {
76 | LabelAvailable.Dispose ();
77 | LabelAvailable = null;
78 | }
79 |
80 | if (LabelEnabled != null) {
81 | LabelEnabled.Dispose ();
82 | LabelEnabled = null;
83 | }
84 |
85 | if (LabelLocation != null) {
86 | LabelLocation.Dispose ();
87 | LabelLocation = null;
88 | }
89 | }
90 | }
91 | }
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests/App.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using Xamarin.Forms;
7 |
8 | namespace GeolocatorTests
9 | {
10 | public class App : Application
11 | {
12 | public App()
13 | {
14 |
15 | // The root page of your application
16 | MainPage = new NavigationPage(new HomePage());
17 | }
18 |
19 | protected override void OnStart()
20 | {
21 | // Handle when your app starts
22 | }
23 |
24 | protected override void OnSleep()
25 | {
26 | // Handle when your app sleeps
27 | }
28 |
29 | protected override void OnResume()
30 | {
31 | // Handle when your app resumes
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests/GeolocatorTests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | netstandard2.0
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/Tests/GeolocatorTests/Utils.cs:
--------------------------------------------------------------------------------
1 | using Plugin.Permissions;
2 | using Plugin.Permissions.Abstractions;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Linq;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 | using Xamarin.Forms;
9 |
10 | namespace GeolocatorTests
11 | {
12 | public static class Utils
13 | {
14 | public static async Task CheckPermissions() where T : BasePermission, new()
15 | {
16 | var permissionStatus = await CrossPermissions.Current.CheckPermissionStatusAsync();
17 | bool request = false;
18 | if (permissionStatus == PermissionStatus.Denied)
19 | {
20 | if (Device.RuntimePlatform == Device.iOS)
21 | {
22 |
23 | var title = $"{nameof(T)} Permission";
24 | var question = $"To use this plugin the {nameof(T)} permission is required. Please go into Settings and turn on {nameof(T)} for the app.";
25 | var positive = "Settings";
26 | var negative = "Maybe Later";
27 | var task = Application.Current?.MainPage?.DisplayAlert(title, question, positive, negative);
28 | if (task == null)
29 | return false;
30 |
31 | var result = await task;
32 | if (result)
33 | {
34 | CrossPermissions.Current.OpenAppSettings();
35 | }
36 |
37 | return false;
38 | }
39 |
40 | request = true;
41 |
42 | }
43 |
44 | if (request || permissionStatus != PermissionStatus.Granted)
45 | {
46 | var newStatus = await CrossPermissions.Current.RequestPermissionAsync();
47 | if (newStatus != PermissionStatus.Granted)
48 | {
49 | var title = $"{nameof(T)} Permission";
50 | var question = $"To use the plugin the {nameof(T)} permission is required.";
51 | var positive = "Settings";
52 | var negative = "Maybe Later";
53 | var task = Application.Current?.MainPage?.DisplayAlert(title, question, positive, negative);
54 | if (task == null)
55 | return false;
56 |
57 | var result = await task;
58 | if (result)
59 | {
60 | CrossPermissions.Current.OpenAppSettings();
61 | }
62 | return false;
63 | }
64 | }
65 |
66 | return true;
67 | }
68 | }
69 | }
70 |
71 |
--------------------------------------------------------------------------------