Giới thiệu
Một trong những tính năng hấp dẫn nhất được cung cấp qua điện thoại là chức năng GPS (ít nhất là cho tôi). Tôi không bao giờ nhận ra rằng tương tác với chức năng GPS là dễ dàng như vậy cho đến khi tôi làm việc với nó. Bài viết này là một cách để giúp mọi người nhận ra như vậy. Bài viết này được nhắm mục tiêu đến một người mới bắt đầu những người muốn thực hiện chức năng GPS và làm việc với Google Maps API.
Trong bài viết này, chúng ta sẽ tạo ra một ứng dụng rất đơn giản được gọi là GPSLocator. GPSLocator hiển thị thông tin từ GPS và hiển thị chính xác (hoặc gần nhất) vị trí trong Google Maps.
Để xây dựng và phát triển GPSLocator, các bạn cần cài đặt các ứng dụng sau:
Ngoài 2 ứng dụng trên, yêu cầu bạn phải cài:
Bước 1: Hướng dẫn lấy Key Google Maps API
Điều đầu tiên và quan trọng nhất là nhận được một Google Maps API key. Nhận được là tương đối dễ dàng, nhưng nó đòi hỏi ứng dụng của chúng ta sẽ được ký kết với một chứng chỉ và thông báo cho Google về dấu vân tay (MD5) Hash chứng nhận. Tiến trình này có thể được chia thành hai phần:
Tạo ra một chứng chỉ và nhận được dấu vân tay MD5
Chúng ta có thể tạo ra một chứng chỉ mới bằng cách sử dụng keytool.exe, được tìm thấy trong thư mục bin của đường dẫn cài đặt JDK (ví dụ C:\Program Files\Java\jdk1.6.0_21\bin). Chúng ta cần phải vượt qua một số thông tin và nó sẽ tạo ra một file keystore. Ảnh chụp:
Lưu ý: Phải chạy CMD dưới quyền Administrator
Để phát triển và thử nghiệm ứng dụng, chúng ta thường đăng ký các ứng dụng trong chế độ Debug. Chúng ta cần đăng ký cho Google Maps API với Hash MD5. Chứng nhận được sử dụng cho mục đích này là debug.keystore. Nó thường được đặt tại:
Để tìm kiếm mã MD5, chạy lệnh sau:
keytool -list -alias androiddebugkey -keystore debug.keystore -storepass android -keypass android
Đầu ra của lệnh thực hiện sẽ giống như hình bên dưới:
Đăng ký cho Google Maps API
Tới trang đăng ký Maps API Key và dán MD5 chính (nêu trên) và chúng ta sẽ nhận được một Maps API key. Các trang web cũng cho thấy làm thế nào để sử dụng API quan trọng trong một MapView.
Tạo một project Android mới và cung cấp các chi tiết như dưới đây. Ngoài ra, hãy chắc chắn chọn API của Google.
Nhấn Finish và project được tạo ra. Tạo một cấu hình Run cho các dự án để khởi động một AVD nhắm mục tiêu Google API (Kiểm tra phần Điều kiện tiên quyết ). Ngoài ra, hãy chắc chắn rằng phiên bản của các API của Google lựa chọn cho AVD và Xây dựng mục tiêu là cùng. Một số ảnh chụp màn hình của cấu hình là:
Hãy thử chạy project với cấu hình như trên và nó sẽ hiển thị như hình:
Bước 3: Thêm Google Map và Quyền
Trước khi chúng ta có thể bắt đầu sử dụng MapView kiểm soát từ các API của Google, chúng ta cần thêm Google Maps bên ngoài Library( com.google.android.map ). Để thêm một thư viện để sử dụng thẻ thư viện. Thẻ này cần phải được thêm vào AndroidManifest.xml. Ngoài thư viện, chúng ta cần thêm các điều khoản có liên quan. Để thêm các điều khoản, chúng ta sử dụng thẻ uses. Đối với các ứng dụng của chúng ta, chúng ta sẽ bổ sung thêm điều khoản sau đây:
- android.permission.ACCESS_COARSE_LOCATION: Cho phép ứng dụng truy cập vào vị trí thô (Cell ID, Wi-Fi ...)
- android.permission.ACCESS_FINE_LOCATION : Cho phép ứng dụng để truy cập vào vị trí GPS.
- android.permission.INTERNET : Cho phép ứng dụng mở network socket.
Để biết thêm thông tin về quyền truy cập, xem Quyền.
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.VertexVerveInc.GPSLocator"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-sdk android:minSdkVersion="15" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<uses-library android:name="com.google.android.maps" />
<activity
android:name=".GPSLocatorActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Cuối cùng, thêm control MapView đến main.xml dưới res/layout. Code sẽ giống như thế:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
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:enabled="true"
android:clickable="true"
android:apiKey="0sk4oLY4DkYt-7aIFtj9ag2_u-nZ6Qt1SPH8ISg"
/>
</LinearLayout>
P/s: 0sk4oLY4DkYt-7aIFtj9ag2_u-nZ6Qt1SPH8ISg là Key mà mình có được từ Bước 1
Bước 4: Hiển thị Google Map
Để hiển thị xem Google Map, chúng ta cần phải cập nhật lớp Activity của chúng ta( GPSLocatorActivity ). Lớp này nên mở rộng lớp MapActivity ở vị trí lớp Activity. Chúng ta cũng cần phải nhập gói com.google.android.maps.MapActivity hỗ trợ lớp MapActivity. Chúng ta cũng cần phải ghi đè lên phương thức isRouteDisplayed của lớp MapActivity. Điều này là khá dễ dàng, chỉ cần trả lại false từ phương thức này. Sau khi tất cả những sửa đổi, GPSLocatorActivity.java giống như:
package com.VertexVerveInc.GPSLocator;
import com.google.android.maps.MapActivity;
import android.os.Bundle;
public class GPSLocatorActivity extends MapActivity
{
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
@Override
protected boolean isRouteDisplayed() {
return false;
}
}
OK. Giờ chạy thử chứ nóng lòng quá rồi @@
Đẹp lắm phải không nào, cứ như "Hãy cho tôi một điểm tựa, tôi sẽ nhấc bổng quả đất lên"
Bước 5: Thêm Control Zoom(in/out)
Lớp MapView có một phương thức setBuiltInZoomControls. Cách gọi phương thức này với true/false enable/disable điều khiển Zoom(in/out). Để gọi phương thức này, chúng ta cần phải tìm các instance của lớp MapView bằng cách gọi findViewById với id của control MapView. Nhớ id="@+id/mapView" từ main.xml. Một điều quan trọng cần lưu ý ở đây là các điều khiển zoom sẽ kích hoạt một lần, chúng ta sẽ chạm/click vào xem bản đồ.
Thay đổi xem bản đồ và mức độ Phóng to
Chúng ta có thể lựa chọn, nếu chúng ta muốn hiển thị xem truyền hình vệ tinh, giao thông hoặc đường trong bản đồ. Điều này chỉ đơn giản là đạt được bằng cách gọi setSatellite, setStreetView và phương thức setTraffic. Một điều cần làm trước khi chúng ta di chuyển xa hơn là zoom bản đồ một chút. Tại sao? Bởi vì giao diện bản đồ được hiển thị trong đầu ra ở trên không phục vụ bất kỳ mục đích nào. Để thiết lập mức độ phóng của bản đồ, chúng ta cần MapController và chúng ta có thể gọi phương thức setZoom. Vì vậy, hãy cập nhật các phương thức onCreate của lớp GPSLocatorActivity để kết hợp tất cả những thay đổi này.
package com.VertexVerveInc.GPSLocator;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import android.app.Activity;
import android.os.Bundle;
public class GPSLocatorActivity extends MapActivity {
private MapView mapView;
private MapController mapController;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mapView = (MapView) findViewById(R.id.mapView);
// enable Street view by default
mapView.setStreetView(true);
// enable to show Satellite view
// mapView.setSatellite(true);
// enable to show Traffic on map
// mapView.setTraffic(true);
mapView.setBuiltInZoomControls(true);
mapController = mapView.getController();
mapController.setZoom(16);
}
@Override
protected boolean isRouteDisplayed() {
return false;
}
}
Chạy ứng dụng coi thế nào :)
Chạy thử xong rồi, thì nhớ xóa để tí chạy không. Không thôi bạn cứ PM hỏi thôi sao làm tiếp mà không chạy nữa nhé @@
Bước 6: Thêm GPS Location Mapping
Android cung cấp vị trí các dịch vụ thông qua lớp LocationManager( package android.Location ). Lớp này cung cấp thông tin cập nhật định kỳ về vị trí của thiết bị. Trong LocationManager , chúng ta cần phải có được reference của lớp LocationManager bằng cách gọi phương thức getSystemService. Sau đó, chúng ta cần phải đăng ký để cập nhật vị trí bằng cách gọi phương thức requestLocationUpdates.
Chúng ta cần tạo ra một lớp thực hiện abstract LocationListener. Lớp này sẽ được đăng ký với Location Manager để nhận được cập nhật vị trí. Chúng ta cần phải ghi đè lên tất cả bốn phương thức của lớp này, cụ thể là onLocationChanged, onProviderDisabled/Enable, và onStatusChanged. Chúng ta chỉ quan tâm đến việc cập nhật vị trí, thay đổi mã của onLocationChanged để điều hướng đến vị trí mới nhận được trong chế độ xem bản đồ. Điều này đạt được bằng cách gọi phương thức animateTo của MapController
package com.VertexVerveInc.GPSLocator;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;
import com.google.android.maps.MapController;
import com.google.android.maps.GeoPoint;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.Geocoder;
import android.location.Address;
import com.google.android.maps.Overlay;
import android.graphics.Canvas;
import android.graphics.Point;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import java.io.IOException;
import android.os.Bundle;
import android.widget.Toast;
public class GPSLocatorActivity extends MapActivity {
private MapController mapController;
private LocationManager locationManager;
private LocationListener locationListener;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationListener = new GPSLocationListener();
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
mapView = (MapView) findViewById(R.id.mapView);
// enable Street view by default
mapView.setStreetView(true);
// enable to show Satellite view
// mapView.setSatellite(true);
// enable to show Traffic on map
// mapView.setTraffic(true);
mapView.setBuiltInZoomControls(true);
mapController = mapView.getController();
mapController.setZoom(16);
protected boolean isRouteDisplayed() {
private class GPSLocationListener implements LocationListener
public void onLocationChanged(Location location) {
GeoPoint point = new GeoPoint(
(int) (location.getLatitude() * 1E6),
(int) (location.getLongitude() * 1E6));
/* Toast.makeText(getBaseContext(),
"Latitude: " + location.getLatitude() +
" Longitude: " + location.getLongitude(),
Toast.LENGTH_SHORT).show();*/
mapController.animateTo(point);
mapController.setZoom(16);
MapOverlay mapOverlay = new MapOverlay();
mapOverlay.setPointToDraw(point);
List<Overlay> listOfOverlays = mapView.getOverlays();
listOfOverlays.add(mapOverlay);
String address = ConvertPointToLocation(point);
Toast.makeText(getBaseContext(), address, Toast.LENGTH_SHORT).show();
public String ConvertPointToLocation(GeoPoint point) {
Geocoder geoCoder = new Geocoder(
getBaseContext(), Locale.getDefault());
List<Address> addresses = geoCoder.getFromLocation(
point.getLatitudeE6() / 1E6,
point.getLongitudeE6() / 1E6, 1);
if (addresses.size() > 0) {
for (int index = 0; index < addresses.get(0).getMaxAddressLineIndex(); index++)
address += addresses.get(0).getAddressLine(index) + " ";
public void onProviderDisabled(String provider) {
public void onProviderEnabled(String provider) {
public void onStatusChanged(String provider, int status, Bundle extras) {
class MapOverlay extends Overlay
private GeoPoint pointToDraw;
public void setPointToDraw(GeoPoint point) {
public GeoPoint getPointToDraw() {
public boolean draw(Canvas canvas, MapView mapView, boolean shadow, long when) {
super.draw(canvas, mapView, shadow);
// convert point to pixels
Point screenPts = new Point();
mapView.getProjection().toPixels(pointToDraw, screenPts);
Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.red);
canvas.drawBitmap(bmp, screenPts.x, screenPts.y - 24, null); // 24 is the height of image
Run Application