
Users do not want to deal with the features of the coordinates, time zones. Some do not even know how these coordinates are expressed, and what time zones are.
How to make the user feel good?
This article will explain how to work with coordinates and time zones:
Namely,
- Installing Google Maps, considered a small functionality with an example.
- Search for a time zone with coordinates (Geonames.org).
- Search for coordinates and time zone by city name (Geonames.org).
- Determining the name of the area by coordinates.
')
So,
User wants:
- It is not enough to think.
- Few click.
Therefore, we just have to teach the phone:
- Find the coordinates and time zone for the name of the city.
- Find time zone by coordinates, if maps are used.
- Find out the current position of the user.
- Find out the exact address by coordinates.
For a hurry:
click the link to go directly to the application and description of the code with comments.
For others. Let's go in order.
Introduction
For a start, what are time zones (time zones). In principle, all this is available on Wikipedia.org, but you can briefly look herePoint on the globe can be determined using two coordinates - latitude and longitude. And this is quite a known fact. But with time zones there is a snag: anywhere in the world there can be absolutely any time zone. It all depends on the level of imagination of a manager in a particular territory.
For example, for clarity, now in European Russia the true noon, which is supposed to be at 12:00, appears almost 2 hours later. On the day of the writing of the article, the true afternoon - the Sun at its zenith in Moscow - was at 13:38. In some territories of Russia, a shift in the passage of the Sun along the zenith is obtained by as much as 3 hours.
Let's go back to the numbers. The world government community was taken for the zero meridian - Greenwich. Time zones are calculated relative to it and as follows. The time zone is the local time shift at some point on the planet relative to the Greenwich meridian. The whole globe is divided into 24 parts along the meridians. That is, the base meridians of 0 °, 15 °, 30 °, etc. are taken, and time zones of ± 7.5 ° are counted from them. Thus, the +00: 00 time zone - and it is denoted differently: both UTC, and GMT, and GMT + 00: 00 (there is a difference between UTC and GMT, but in practice in most cases this does not apply) - is from 7.5 ° W. to 7.5 ° E, GMT + 01: 00 - from 7.5 ° E up to 22.5 ° east and so on. But, besides this, there are also state borders, as well as some of the states are in the so-called middle zone, where it is economically feasible to make a shift of +01: 00 in the summer (usually). In the southern hemisphere, summer shift occurs when it is winter in northern. In Russia, the maternity time was also applied, due to which the clock was moved another hour forward. On the seas and oceans, the time zone is used, which is calculated from the position in the usual way. And in Antarctica, in general, a separate story, how to calculate this business. Due to all these socio-economic and political reasons, several hundreds of time zones accumulated on the planet. And if the program also needs to use time (and time zones change in time), then with all these shifts, you can get confused.
By the way, it happens that the Calendar
class in Java
generates an error with an hour shift, if you initialize, for example, with the current time and time zone, and then set the time before we switched exclusively to summer time, for example, 1988, then the calendar will display the clock with a shift of 1 hour. This is treated if constantly reinstalling the calendar when installing new milliseconds. SimpleDateFormat
always produces a similar error, therefore I do not advise using it for old dates.
Link to the “time zone” article on WikipediaGeonames.org is a great resource. There you can both download databases and use the native API for this resource. In this article I will use just the API.
To work with Geonames, you need to register a user with which you will have access to the API. And also
do not forget to activate it . To do this,
go to your account and click on the link:
Click here to enable .
Here is the documentationThere is even a library for access , but I personally do not use the library, because sometimes errors occur. Directly with the API via http-request work more clearly.
License . You can use this product for free.
Everyone knows about Google Maps.
You can general help on using Google Maps
can be found here .
There is also such a feature as GeoCoder. You can find the address by coordinates. But time zones, for some reason there is not.
I will also use
Geonames.org to search for time zones on a click.
Setting up Google Maps
For beginners, a brief editing algorithm
AndroidManifest.xml
, what to get from, to work Google Maps and determine the position of the phone.
Who is not interested -
click here to scroll directly to the description of the features of the application .
one.
inside
<manifest>
:
<permission android:name="com.example.android.permission.MAPS_RECEIVE" android:protectionLevel="signature" /> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-feature android:glEsVersion="0x00020000" android:required="true"/>
2
inside
<application>
:
<meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" /> <meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="API_KEY"/>
To get android: value = "API_KEY" (
link where it is in the code ), you need:
- here
APIs & auth > Credentials > Create new KEY > Android key
- In the field we write the following SHA-1-KEY; com.example.android.mapexample
Pictures for android: value = "API_KEY"
features of receiving SHA-1-KEY
- it happens either debug or release. It is obtained from the certificate file.
- file certificate for debug - taken from% USERPROFILE% \. android \ debug.keystore. It is tied to the computer and Eclipse.
- file certificate for release is my-release-key.keystore, which is used to digitally sign the application. Every developer knows about it. You can get it like this: developer.android.com/tools/publishing/app-signing.html#cert
- in order to get debug-key. open the documentation , and then there is the section Displaying the debug certificate fingerprint and see how to do it
- to get a release-key, you need to open the documentation , there is a section Displaying the release certificate certificate fingerprint
- In the current version of api-console, you can make several combinations of SHA-1-KEY; com.example.android.mapexample for one output API_KEY. Conveniently with one key on multiple computers.
For Google Maps to work, add an Android library to your project. The path is:
<Android-SDK-Path>\extras\google\google_play_services\
. You need to add this:
File>New>Project>Android>Android Prject from Existing Code>Next
Do not forget to add the
google_play_services
project as a library in the
google_play_services
main project
habrtimezone
. This should be done in
Project>Properties>Android>Library>Add...
You need to build a project for Google APIs 4.4.2 (you can> 4.0). To do this, check the corresponding list item in
Project>Properties>Android>Project Build Target
. If there is no such item, then you need to install Google APIs through the Android SDK Manager.
A picture that shows where and what to include. What to download in the Android SDK Manager. Application code
Below is an example of an application that is available on
Google Play , the source code is on
GitHub .
There will be comments on the features of the application.
Screenshot Eclipse with the project. So, what can the application:
1. Determine current coordinates
2. Work with the card
3. Determine the position of the city and its time zone by its name.
I will not explain all aspects of the application, but only show the main details and features.
In the presence of a code with trifles it is not difficult to figure it out.
Class AMain. First screen
The application starts working with
AMain
Activity
Class
AMain.java
.
Class code public class AMain extends Activity implements OnClickListener
(
link )
OnClickListener - for handling clicks. In my opinion, it is better to handle clicks this way, since the memory will be consumed in smaller quantities if you use
button.setOnClickListener(this);
, but not
button.setOnClickListener(< Listener>);
This effect is especially noticeable when using a large number of clickable objects.
(
link for button and
link for handler )
What's going on here:
There is a search for the coordinates of the phone in space using GSM towers, as well as GPS.
Through this window you can open:
1. Map. For markers on this map, the current position of the phone and the position (latitude / longitude), which is recorded in the
AGMap
text fields, will be
AGMap
2. Search for cities via the Internet.
ACityListOnline
The search for coordinates was made using the following main objects:
private LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE); private LocationListener gpsLocationListener; private LocationListener networkLocationListener;
(
link )
As the coordinates and / or time change, the event will be processed using the
LocListener implements LocationListener
(
link ) in
@Override public void onLocationChanged(Location location) {}
(
link )
Work with the card
Class AGMap. Screen to work with the map
In order for the map to be in the application, you need to create the following block in the resources in the
agmap.xml
file (
link ):
<fragment android:id="@+id/map" android:layout_width="match_parent" android:layout_height="match_parent" class="com.google.android.gms.maps.SupportMapFragment"/>
Which is the map. (
link )
Activity class:
AGMap.java
Class code .
What's going on here.
1. The map opens,
2. Coordinates from the previous screen are transferred to it.
3. There are 2 markers - the current coordinates, and a marker in the center of the screen.
4. You can move the map, when you click on the Save button, the coordinates of the center of the map will be applied, the name of the region will be determined, the time zone will be determined using Geonames.org.
Features of setting and using the card.
public class AGMap extends FragmentActivity implements OnCameraChangeListener, OnClickListener
(
link )
FragmentActivity
- since the card is included in this Activity, from the parent one should use this class.
OnCameraChangeListener
- needed to handle the movement of the map
private GoogleMap mMap;
which is initialized as follows:
mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap();
(
link )
Positions of objects (pointers on the map) are stored in
LatLng HEREIAM = null;
(
link )
In order to draw a marker, you need to make an object with marker settings
mo = new markerOptions(...
(
link )
and apply it to the map:
mar = mMap.addMarker(mo);
the output will be
Marker mar
(
link )
I noticed that on some devices, when initializing the map, an error occurs in
onCreate()
, so you have to wrap the error in
try{}catch(NullPointerException e){}
(
link )
All map settings are
GoogleMapOptions options = new GoogleMapOptions();
(
link )
Map marker centering:
@Override public void onCameraChange(CameraPosition cp) {
(
link )
Initially, the result processing functions have been added to this function.
uniqueExec();
But in case of a bad connection, everything will slow down. It is inconvenient to use.
The search for the position name is as follows:
Geocoder geoCoder = new Geocoder(getBaseContext(), Locale.getDefault()); try { List<Address> addresses = geoCoder.getFromLocation(point.latitude, point.longitude, 1);
(
link )
To be fair, it’s worth adding that the “Service not Available” error sometimes occurs. In this case, it is better to supplement this function by checking the form.
if (Geocoder.isPresent()){} else{}
and in
else
make a direct request by
URL
:
String googleMapUrl = "http://maps.googleapis.com/maps/api/geocode/json?latlng=" + point.latitude + "," + point.longitude + "&sensor=false&language=" + Locale.getDefault().getLanguage();
In this case,
it will be necessary to add an
if-else
condition
here .
The output will be a JSON object, which is also broken down into pieces, as is the case with GeoNames. (
See just below )
Unfortunately, there is a limit to 2500 requests per day in the case of the free option.
More hereWhen you click the save button (
link ), the following happens:
1. search for the name of the area by coordinates in the center of the screen. Done using
geocodertask extends AsyncTask<Void, Integer, Void>
(
link ) in the function
uniqueExec();
(
link )
2. Search for a time zone by coordinates in the center of the screen. Done using
TimeZoneTask extends AsyncTask<Double, Integer, Void>
(
link ) in the function
uniqueExecTZ(pos);
(
link )
Requests for http for
Geocoder
and
Time Zone
wrapped in
AsyncTask
(
link 1 and
link 2 ), because access to the Internet must occur asynchronously, without clogging the main thread.
In fact, the main part of the application and this article is a few requests on Geonames.org. Here is the first one.
String[] urlString = {"http://api.geonames.org/findNearbyJSON?lat=","&lng=", "&radius=50&username=","&style=full&maxRows=1"}; outURL = urlString[0] + f.format(lat).replace(",", ".") + urlString[1] + f.format(lon).replace(",", ".") + urlString[2] + _.names1[r.nextInt(_.names1.length)] + urlString[3];
(
link 1 )
(
reference 2 )
The request searches for any one object at a distance closer than 50 km. If this object has a time zone, this is the result. If not, or such objects are not detected (for example, located somewhere in the ocean), then the time zone is calculated by the current latitude and longitude with the usual division of the globe into 24 parts (
link ). Perhaps the object is not chosen arbitrarily, but the closest one is taken, but I did not check it in detail.
The result is displayed in JSON format. Therefore, in parallel, you can pull out and other information.
The
names1
array (
reference ) from the
_.java
class stores logins on Geonames.org. You can store one login, but several are better, since there is a limit on the number of requests per hour. In this case, by increasing the number of users and choosing them randomly, it will be possible to proportionally increase the number of requests in such an artificial way. The choice of the user through which the connection occurs, occurs randomly using r.nextInt () (
which is r ). In the license I did not find restrictions for a similar trick.
Once again I will write.
Attention , do not forget to
activate the user . To do this,
go to your account and click on the link:
Click here to enable .
The method, of course, is not absolutely accurate, but it is working. And usually this method is quite enough. No complaints from end users yet.
Class ACityListOnline. On this screen, cities are searched by name.
Activity
ACityListOnline.java
Class code .
Also used by Geonames.org in
CityTask extends AsyncTask<String, Integer, Void>
(
reference to class )
(
this is the launch of the CityTask class object )
Here the requests are similar to
AGMap.java
, but the search is performed by name.
Here is the second of those queries that work with GeoNames:
String[] urlString = {"http://api.geonames.org/searchJSON?q=", "&username=","&style=full"}; outURL = urlString[0] + URLEncoder.encode(str, "UTF-8") + urlString[1] + _.names1[r.nextInt(_.names1.length)] + urlString[2];
(
link 1 )
(
reference 2 )
If the result is found, it is stored in an object of class
_Info
(
reference to class )
(
link to the list of class objects that store search results )
Further details can be viewed in another Activity by clicking on the
ListView
item.
Now the object of class
_Info
stores the latitude, longitude, time zone and the international name of the region. If you want to pull out other information (it is also available), you can take it from the JSON object yourself. Everything is simple and tedious.
results
According to the main functionality everything.
Once again link to
google play .
Before you use the code on
GitHub, pay
attention to :
There are no Geonames.org users in this code.
Namely, it will be necessary to insert user names into the variable
public static final String[] names1 = {"your_account_1","your_account_2"};
in the
_.java
class (
link ), and also insert your
API_KEY
. in
AndroidManifest.xml
(
link )
How to get these values, I explained above.
In order for the project with GitHub to gather, you need to add this file to
Project>Properties>Java Build Path>Libraries>Add External JARs
:
Android_SDK_Path\extras\android\support\v4\android-support-v4.jar
. Then go to
Project>Properties>Java Build Path>Order and Export
and include this file.
If there is interest in such an article, I can tell you next time how this can be done locally without an internet connection.