В этом руководстве вы узнаете, как использовать API Карт Google для наложения точек интереса (POI) и использовать доступные службы на основе местоположения на своем телефоне, чтобы показать свое положение относительно доступных местоположений POI. В этом случае мы будем использовать торговые центры в качестве POI.
Я разделил этот урок на две части. Часть 1 (урок, представленный в этом уроке) будет охватывать:
- Использование объекта MapView
- Используя ваш отпечаток MD5, чтобы получить ключ API для использования Google Maps
- Реализация прослушивателя местоположения для получения вашего текущего местоположения
Часть 2 будет охватывать:
- Использование внешних библиотек в вашем приложении
- Создание наложений для отображения вашего текущего местоположения и различных достопримечательностей
Теперь начнем!
Шаг 1. Создайте новый проект Android
Запустите Eclipse IDE и создайте новый проект Android. Для этого в Eclipse IDE перейдите к:
Файл> Создать> Новый проект Android
Создайте новый проект со следующими настройками:
Название проекта : MallFinder
Цель построения : Платформа API Google — 2.1 Уровень API 7
Название приложения : Mall Finder
Название пакета : com.shawnbe.mallfinder
Создать активность : MallFinderActivity
MinimumSDK : 7
После настройки параметров нажмите Готово.
Шаг 2. Зарегистрируйтесь в Google для получения ключа API.
Поскольку объекты MapView используют Google Maps, вам необходимо зарегистрироваться в Google для получения ключа API и принять Условия использования, прежде чем вы сможете их использовать. Этот процесс довольно прост и безболезнен, и мы пройдем этот процесс шаг за шагом. Для получения дополнительной информации перейдите по этой ссылке на Получение ключа API Карт .
Чтобы сгенерировать ключ API, вам понадобится ваш отпечаток MD5 сертификата, который вы будете использовать для подписи приложения. Звучит странно, я знаю, но это не так сложно, как кажется, как вы обнаружите, пока мы будем проходить различные этапы. Вместо использования метода командной строки для получения отпечатка вашего MD5, как описано в приведенной выше ссылке, мы будем использовать плагин keytool для Eclipse. Для получения дополнительной информации о плагине keytool посетите этот веб-сайт .
Шаг 3: Установка плагина Keytool
Находясь в Eclipse IDE, выберите «Справка»> «Установить новое программное обеспечение».
Когда появится новое окно, нажмите кнопку «Добавить» в верхней части окна.
Введите «keytool» (без кавычек) в поле имени и
http://www.keytool.sourceforge.net/update в поле местоположения.
Нажмите ОК.
После короткого времени загрузки во всплывающем окне появится флажок «keytool». Установите флажок и нажмите «Далее». Ознакомьтесь с условиями лицензионного соглашения и нажмите «Далее» для завершения.
Примечание. Во время установки вам может быть предложено определить, доверяете ли вы сертификатам безопасности. Если вы это сделаете, установите флажок и нажмите OK, чтобы продолжить установку.
После установки вам будет предложено перезапустить Eclipse. Сделай так и продолжай.
Шаг 4: Получение отпечатка пальца MD5
После перезапуска Eclipse вы увидите новый пункт меню «Keytool» с небольшим значком ключа рядом с ним.
Теперь мы собираемся открыть хранилище ключей отладки. Примечание: расположение может отличаться в зависимости от вашей операционной системы. Местоположения по умолчанию для различных операционных систем:
- Windows Vista: C: \ Users \ <пользователь> \. Android \ debug.keystore
- Windows XP: C: \ Documents and Settings \ <пользователь> \. Android \ debug.keystore
- OS X и Linux: ~ / .android / debug.keystore
Нажмите на пункт меню Keytool> открыть хранилище ключей.
Нажмите кнопку «Обзор», расположенную справа от текстового поля «Имя файла», перейдите в папку хранилища ключей отладки (расположение по умолчанию выше) и выберите файл debug.keystore.
Нажмите «Открыть» и введите «android» (без кавычек), который является паролем отладки по умолчанию, а затем нажмите «Загрузить».
Новая вкладка Keytool теперь должна быть видна в нижней панели экрана (если вы ее не видите, перейдите в Window> Open Perspective> Java Browsing).
Нажмите на маленькую стрелку слева от пути к debug.keystore, чтобы отобразить androiddebugkey.
Дважды щелкните на androiddubugkey и скопируйте отпечаток MD5.
Откройте веб-браузер и перейдите по следующему URL. http://code.google.com/android/maps-api-signup.html
Ознакомьтесь с условиями и, если вы согласны, введите отпечаток MD5 в текстовое поле и нажмите «Создать ключ API». Запишите ваш ключ API, так как он необходим для работы MapView.
Шаг 5: Добавьте MapView к макету
На этом этапе мы будем добавлять MapView в файл макета.
Откройте файл main.xml, расположенный в MallFinder> res> layout> main.xml, и обновите файл, включив в него FrameLayout и MapView, как показано ниже:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
|
<?xml version=»1.0″ encoding=»utf-8″?>
<LinearLayout xmlns:android=»http://schemas.android.com/apk/res/android»
android:layout_width=»fill_parent»
android:layout_height=»fill_parent»
android:orientation=»vertical» >
<FrameLayout
android:layout_width=»fill_parent»
android:layout_height=»fill_parent»>
<com.google.android.maps.MapView
android:id=»@+id/mapView»
android:layout_width=»fill_parent»
android:layout_height=»fill_parent»
android:clickable=»true»
android:apiKey=»PUT YOUR API KEY HERE»/>
</FrameLayout>
</LinearLayout>
|
Вышеприведенный макет создает MapView по всему доступному экранному пространству. Прежде чем мы сможем запустить приложение и увидеть MapView, необходимо выполнить еще несколько шагов. Запуск приложения в его текущем состоянии приведет к принудительному закрытию.
Шаг 6. Настройка разрешений и объявление необходимых библиотек.
Поскольку наше приложение будет загружать данные из Google Maps, а также для доступа к информации из GPS-трубки или других служб на основе местоположения, нам потребуется запросить необходимые разрешения для использования этих служб и функций в файле манифеста Android.
Для этого откройте файл манифеста Android, расположенный в MallFinder> AndroidManifest.xml.
Добавьте следующие строки после закрывающего тега приложения (</ application>), но перед закрывающим тегом манифеста (</ manifest>).
1
2
3
|
<uses-feature android:name=»android.hardware.location.gps»/>
<uses-permission android:name=»android.permission.ACCESS_FINE_LOCATION»/>
<uses-permission android:name=»android.permission.INTERNET»/>
|
В этом примере мне не понадобится FINE_LOCATION, но я включил это здесь, поскольку я полагаю, что вы, возможно, захотите внести изменения в свой код для тестирования различных поставщиков, если вы хотите получить наиболее точное местоположение, вам потребуются разрешения FINE_LOCATION , Как правило, для любого производственного приложения не следует запрашивать разрешения, которые вам не нужны. Это очень плохая практика, и пользователь опасается вашего приложения, когда вы запрашиваете дополнительные разрешения. Если вы не собираетесь использовать наиболее точных поставщиков, вы можете настроить разрешение на android.permission.ACCESS_COARSE_LOCATION.
Чтобы использовать Google Maps в нашем MapView, нам нужно объявить библиотеку в нашем файле манифеста, поэтому давайте сделаем это, добавив следующий код между закрывающим тегом активности и закрывающим тегом приложения:
1
|
<uses-library android:required=»true» android:name=»com.google.android.maps» />
|
Поскольку мы уже находимся в файле манифеста Android, давайте избавимся от строки заголовка, так как я считаю это ненужным. Он использует слишком много нашего ограниченного экранного пространства. Чтобы удалить его, добавьте строку ниже в тег приложения:
1
|
android:theme=»@android:style/Theme.NoTitleBar»
|
Вот и все для редактирования нашего файла манифеста, поэтому наш полный файл манифеста теперь выглядит так:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
<?xml version=»1.0″ encoding=»utf-8″?>
<manifest xmlns:android=»http://schemas.android.com/apk/res/android»
package=»com.shawnbe.mallfinder»
android:versionCode=»1″
android:versionName=»1.0″ >
<uses-sdk android:minSdkVersion=»7″ />
<application
android:icon=»@drawable/ic_launcher»
android:label=»@string/app_name»
android:theme=»@android:style/Theme.NoTitleBar»>
<activity
android:label=»@string/app_name»
android:name=».MallFinderActivity» >
<intent-filter >
<action android:name=»android.intent.action.MAIN» />
<category android:name=»android.intent.category.LAUNCHER» />
</intent-filter>
</activity>
<uses-library android:required=»true» android:name=»com.google.android.maps» />
</application>
<uses-feature android:name=»android.hardware.location.gps»/>
<uses-permission android:name=»android.permission.ACCESS_FINE_LOCATION»/>
<uses-permission android:name=»android.permission.INTERNET»/>
</manifest>
|
Шаг 7: Настройка MapView
Прежде чем мы сможем увидеть MapView в действии, нам нужно внести несколько изменений в класс MallFinderActivity.
Откройте основной класс активности (MallFinderActivity.java), который находится по адресу:
MallFinder> src> com.shawnbe.mallfinder> MallFinderActivity.class
В нашем приложении нам нужен этот класс для расширения MapActivity, а не Activity для MapView.
Обновите строку:
1
|
public class MallFinderActivity extends Activity {
|
чтобы:
1
|
public class MallFinderActivity extends MapActivity {
|
При расширении класса MapActivity нам необходимо реализовать метод isRouteDisplayed()
, поэтому нам также необходимо добавить следующий скелетный метод:
1
2
3
4
5
|
@Override
protected boolean isRouteDisplayed() {
// TODO Auto-generated method stub
return false;
}
|
На этом этапе мы можем запустить приложение и отобразить MapView, но давайте установим несколько параметров, таких как уровень масштабирования и видимые слои. Мы начнем с объявления следующих переменных перед методом onCreate:
1
2
|
private MapController mapController;
private MapView mapView;
|
Добавьте следующие строки кода в метод onCreate
.
1
2
3
4
5
6
|
mapView = (MapView)findViewById(R.id.mapView);
mapView.setBuiltInZoomControls(true);
mapView.setSatellite(false);
mapView.setStreetView(true);
mapController = mapView.getController();
mapController.setZoom(13);
|
Приведенный выше код отображает только слой Street и скрывает слой Satellite. Я выбрал это как личное предпочтение, так как мне легче читать в этом формате. Не стесняйтесь настраивать это по своему усмотрению, изменяя логические значения false и true. Кроме того, уровень масштабирования установлен на 13, однако его также можно отрегулировать, используя 1, представляющий собой весь мир, а 20 — максимальный масштаб.
Наконец, мы можем запустить приложение и убедиться, что до этого момента все работает как положено.
Существует несколько способов запуска приложения, первый:
Щелкните правой кнопкой мыши на Project в окне Package Explorer> Запуск от имени> Приложения Android
Или
В меню выберите «Выполнить»> «Выполнить».
Затем выберите свой телефон или эмулятор. Вы должны увидеть карту, покрывающую весь ваш экран, за исключением панели уведомлений в верхней части экрана, а также иметь возможность прокручивать и использовать масштабирование для увеличения.
Шаг 8: Получение вашего текущего местоположения
Чтобы получить ваше текущее местоположение, мы используем класс locationManager
, который позволяет приложению получить местоположение устройства. Этот процесс может занять некоторое время, чтобы получить исправление для текущего местоположения, поэтому рекомендуется использовать ваш lastKnownLocation
пока вы не сможете получить более точное исправление для вашего текущего местоположения.
Объявите еще две переменные прямо под теми, которые мы объявили на шаге 7 выше:
1
2
|
private LocationManager locationManager;
private GeoPoint currentLocation;
|
Кроме того, добавьте следующие методы в класс MallFinderActivity.java
:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
public void getLastLocation(){
String provider = getBestProvider();
currentLocation = locationManager.getLastKnownLocation(provider);
if(currentLocation != null){
setCurrentLocation(currentLocation);
}
else
{
Toast.makeText(this, «Location not yet acquired», Toast.LENGTH_LONG).show();
}
}
public void animateToCurrentLocation(){
if(currentPoint!=null){
mapController.animateTo(currentPoint);
}
}
public String getBestProvider(){
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
criteria.setPowerRequirement(Criteria.NO_REQUIREMENT);
criteria.setAccuracy(Criteria.NO_REQUIREMENT);
String bestProvider = locationManager.getBestProvider(criteria, true);
return bestProvider;
}
public void setCurrentLocation(Location location){
int currLatitude = (int) (location.getLatitude()*1E6);
int currLongitude = (int) (location.getLongitude()*1E6);
currentLocation = new GeoPoint(currLatitude,currLongitude);
currentLocation = new Location(«»);
currentLocation.setLatitude(currentPoint.getLatitudeE6() / 1e6);
currentLocation.setLongitude(currentPoint.getLongitudeE6() / 1e6);
}
|
Добавьте следующие две строки в конец метода onCreate:
1
2
|
getLastLocation();
animateToCurrentLocation();
|
Метод onCreate теперь выглядит так:
01
02
03
04
05
06
07
08
09
10
11
12
|
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mapView = (MapView)findViewById(R.id.mapView);
mapView.setBuiltInZoomControls(true);
mapView.setSatellite(false);
mapView.setStreetView(true);
mapController = mapView.getController();
mapController.setZoom(13);
getLastLocation();
animateToCurrentLocation();
}
|
Метод getLastLocation создает экземпляр класса locationManager и на основе требований определяет, какой поставщик лучше всего использовать для служб определения местоположения. В приведенном выше коде мы не указываем никаких критериев для провайдера, однако вы можете откорректировать критерии на основе ваших требований к точности и мощности с помощью методов crit.setAccuracy () и crit.setPowerRequirement (). На шаге 6 выше я упомянул, что вы можете изменить критерии, чтобы получить наиболее точное местоположение. Если вы хотите сделать это, вы должны установить критерии точности ACCURACY_FINE, и строка кода будет выглядеть так:
1
|
criteria.setAccuracy(Criteria.ACCURACY_FINE);
|
Причина, по которой я не выбрал наиболее точного поставщика (то есть GPS), заключается в том, что я буду тестировать этот код в помещении и, возможно, никогда не получу блокировку моей позиции, но не стесняйтесь проверить это для себя, изменить точность и выйти на улицу. и посмотрим, сможете ли вы получить GPS-блокировку вашего текущего местоположения.
В зависимости от указанных критериев ваш телефон может использовать разных поставщиков, обычно это GPS или сеть (но могут отличаться). Последнее известное местоположение затем устанавливается как currentLocation, по крайней мере, до тех пор, пока мы не получим более точное и обновленное местоположение. Широта и долгота текущего местоположения тогда найдены, и мы анимируем или прокручиваем карту, чтобы центрировать вокруг этих координат.
Теперь, когда у нас есть последняя известная позиция, мы используем приемник местоположения, чтобы обнаружить изменения в нашем местоположении и обновить приложение, когда эти изменения происходят. Для этого нам нужен наш класс активности (MallFinderActivity.java) для реализации locationListener. Сначала мы обновляем строку:
1
|
public class MallFinderActivity extends MapActivity {
|
чтобы:
1
|
public class MallFinderActivity extends MapActivity implements LocationListener{
|
Реализация прослушивателя местоположения требует от нас переопределения нескольких методов, поэтому мы добавляем ниже следующие barebone-методы (когда я ссылаюсь на скелетные или barebone-методы, я имею в виду оболочку для методов, но они на самом деле ничего не делают в на этот раз):
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
|
@Override
public void onLocationChanged(Location arg0) {
// TODO Auto-generated method stub
}
@Override
public void onProviderDisabled(String arg0) {
// TODO Auto-generated method stub
}
@Override
public void onProviderEnabled(String arg0) {
// TODO Auto-generated method stub
}
@Override
public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
// TODO Auto-generated method stub
}
|
Мы будем использовать метод onLocationChanged
для обнаружения любых обновлений в нашем местоположении и затем установить его как наше текущее местоположение с помощью метода setcurrentLocation.
Обновите метод onlocationChanged, чтобы отразить следующее:
1
2
3
4
5
|
@Override
public void onLocationChanged(Location newLocation) {
// TODO Auto-generated method stub
setCurrentLocation(newLocation);
}
|
Добавьте следующие строки кода. Эти методы запрашивают обновления каждую секунду, когда приложение запускается или возобновляется, а также прекращает проверку обновлений, когда приложение приостановлено или остановлено.
01
02
03
04
05
06
07
08
09
10
11
|
@Override
protected void onResume() {
super.onResume();
locationManager.requestLocationUpdates(getBestProvider(), 1000, 1, this);
}
@Override
protected void onPause() {
super.onPause();
locationManager.removeUpdates(this);
}
|
Если вы запустите приложение в этот момент, MapView должен сосредоточиться вокруг вашего последнего известного местоположения, а когда ваша трубка сможет получить исправление, оно обновится, чтобы сосредоточиться вокруг вашего текущего местоположения. В зависимости от критериев точности, установленных на шаге 7, время, в течение которого можно определить местоположение, будет различным. В этом уроке мы узнали, как использовать MapView, реализовать locationListener и получить ваше текущее местоположение. В следующем уроке мы будем расширять этот раздел и включать внешнюю библиотеку для обработки наложений в MapView и показывать некоторую информацию во всплывающих подсказках при нажатии на различные точки интереса.