מפות רבותי, מפות, אז אחרי ש Google עשתה את כל העבודה כשמיפתה את העולם ופתחה אותו לכל מי שרק חופץ, העסק נהפך להרבה יותר פשוט, אם תשאלו אותי לפני ש Google החליטה לבצע כזה צעד נועז בתור מפתח לא חשבתי שבכלל תהיה לי היכולת להשתמש במערכות מיפוי, העסק תמיד היה נראה לי מסובך ומצריך משאבים רבים, Google החליטה לתת השירות באופן חופשי עבור משתמשי Android ולאפשר למפתחים לשלב שירותי מיפוי באפליקציות שלהם ללא תשלום, ובשילוב ה Gps שבמכשירים ניתן לפתח אפליקציות מיקום מתקדמות.
במאמר זה אני יעבור על תהליך ההתממשקות ושלב כתיבת האפליקציה ב Android.
שימו לב! - המאמר עובר על תהליך ההתממשקות בגרסת Google Maps Api 2 בשילוב גרסת Api 10 של Android.
התממשקות לשירותי Google
תחילה יש להירשם ל Google (מי שעוד לא הספיק) יש להיכנס לאתר API Console ואח"כ לבחור את ה Api המתאים ברשימת ה Services.
לאחר מכן נגדיר את המפתח עבור האפליקציה, נלחץ על Create New Android Key:
במקרה של עבודה של Debug ניתן להכניס את המפתח ה Default ולהוסיף את שם ה Package שלנו כפי שניתן לראות בדוגמה:
45:B5:E4:6F:36:AD:0A:98:94:B4:02:66:2B:12:17:F2:56:26:A0:E0;com.example
במקרה של Release צריך לייצר מפתח חדש בעזרת הכלי Keytool, את מחרוזת ה SHA1 נטען בתור המפתח ולאחר מכן נרשום אותו ב Manifest כפי שמוצג בהמשך.
יצירת פרויקט:
לפני שניצור פרוייקט חדש חשוב לוודא ש Google Services Api מותקן כחלק מ Android Api 10, בנוסף יש להתקין את הדוגמאות עבור ה SDK.
ניצור פרוייקט חדש ב Eclipse של Android, ונשנה את ה Android Build Target ל Google Api, נוסיף פרויקט נוסף ב Workspace שנקרא google_play_services_lib הוא נמצא בתיקיית ה Extra של ה SDK ונוסיף אותו ב Library בפרויקט כפי שניתן לראות בדוגמה:
קוד:
הקוד עצמו יחסית פשוט , ניצור מחלקה שיורשת FragmentActivity ונחבר Interface מסוג LocationListener, נממש מספר פונקציות ונגדיר את ה Service Provider ע"פ החומרה הקיימת במכשיר על מנת לקבל את המיקום, נסמן את עצמנו במפה ונדאג לעדכן את המיקום בכל פרק זמן או מרחק שעברנו.
Activity
package com.example.urban;
import com.google.android.gms.maps.*;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.content.Context;
import android.graphics.Color;
import android.view.Menu;
import android.view.View;
import android.widget.Toast;
import android.support.v4.app.FragmentActivity;
public class GoogleMapActivity2 extends FragmentActivity implements LocationListener {
private GoogleMap mymap;
private LocationManager locationManager;
private String provider;
private Marker locationMarker;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_google_map_activity2);
set_titlecolor();
//get map component from activity
mymap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap();
//map.setMyLocationEnabled(true);
//set location manager and start active and checking availability of location service
LocationManager service = (LocationManager) getSystemService(LOCATION_SERVICE);
//check for GPS
boolean enabledGPS = service
.isProviderEnabled(LocationManager.GPS_PROVIDER);
//check for WIFI
boolean enabledWiFi = service
.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
//Check if GPS enable throw error
if (!enabledGPS) {
Toast.makeText(this, "GPS signal not found", Toast.LENGTH_LONG).show();
}
Location location = get_location();
// Initialize the location fields
if (location != null) {
Toast.makeText(this, "Selected Provider " + provider,
Toast.LENGTH_SHORT).show();
onLocationChanged(location);
}
}
private void set_titlecolor()
{
//just for fun change title color
View title = getWindow().findViewById(android.R.id.title);
View titleBar = (View) title.getParent();
titleBar.setBackgroundColor(Color.argb(100, 58, 58, 58));
}
private Location get_location()
{
//getting the location manager
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
//define new Criteria for location service
Criteria criteria = new Criteria();
//request accuracy fine => GPS provider
criteria.setAccuracy(Criteria.ACCURACY_FINE);
provider = locationManager.getBestProvider(criteria, false);
Location location = locationManager.getLastKnownLocation(provider);
return location;
}
@Override
protected void onResume() {
super.onResume();
//request to update location every 200 millisecond, and every 1 meter
locationManager.requestLocationUpdates(provider,200, 1, this);
}
/* Remove the locationlistener updates when Activity is paused */
@Override
protected void onPause() {
super.onPause();
locationManager.removeUpdates(this);
}
@Override
public void onLocationChanged(Location location) {
double lat = location.getLatitude();
double lng = location.getLongitude();
Toast.makeText(this, "Location " + lat+","+lng,
Toast.LENGTH_LONG).show();
LatLng coordinate = new LatLng(lat, lng);
Toast.makeText(this, "Location " + coordinate.latitude+","+coordinate.longitude,
Toast.LENGTH_LONG).show();
//remove the marker if exists
if(locationMarker != null)
locationMarker.remove();
//add marker to map
locationMarker = mymap.addMarker(new MarkerOptions()
.position(coordinate)
.title("Are You Spy On Me?")
.snippet("don't expose your position!")
.icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_launcher)));
//going to update the camera with the new coordinates
CameraUpdate center=
CameraUpdateFactory.newLatLng(new LatLng(coordinate.latitude,
coordinate.longitude));
//set camera zoom
CameraUpdate zoom=CameraUpdateFactory.zoomTo(17);
//move camera to location
mymap.moveCamera(center);
mymap.animateCamera(zoom);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.google_map_activity2, menu);
return true;
}
@Override
public void onProviderDisabled(String arg0) {
Toast.makeText(this, "Enabled new provider " + provider,
Toast.LENGTH_SHORT).show();
}
@Override
public void onProviderEnabled(String arg0) {
Toast.makeText(this, "Disabled provider " + provider,
Toast.LENGTH_SHORT).show();
}
@Override
public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
// TODO Auto-generated method stub
}
}
import com.google.android.gms.maps.*;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.content.Context;
import android.graphics.Color;
import android.view.Menu;
import android.view.View;
import android.widget.Toast;
import android.support.v4.app.FragmentActivity;
public class GoogleMapActivity2 extends FragmentActivity implements LocationListener {
private GoogleMap mymap;
private LocationManager locationManager;
private String provider;
private Marker locationMarker;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_google_map_activity2);
set_titlecolor();
//get map component from activity
mymap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap();
//map.setMyLocationEnabled(true);
//set location manager and start active and checking availability of location service
LocationManager service = (LocationManager) getSystemService(LOCATION_SERVICE);
//check for GPS
boolean enabledGPS = service
.isProviderEnabled(LocationManager.GPS_PROVIDER);
//check for WIFI
boolean enabledWiFi = service
.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
//Check if GPS enable throw error
if (!enabledGPS) {
Toast.makeText(this, "GPS signal not found", Toast.LENGTH_LONG).show();
}
Location location = get_location();
// Initialize the location fields
if (location != null) {
Toast.makeText(this, "Selected Provider " + provider,
Toast.LENGTH_SHORT).show();
onLocationChanged(location);
}
}
private void set_titlecolor()
{
//just for fun change title color
View title = getWindow().findViewById(android.R.id.title);
View titleBar = (View) title.getParent();
titleBar.setBackgroundColor(Color.argb(100, 58, 58, 58));
}
private Location get_location()
{
//getting the location manager
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
//define new Criteria for location service
Criteria criteria = new Criteria();
//request accuracy fine => GPS provider
criteria.setAccuracy(Criteria.ACCURACY_FINE);
provider = locationManager.getBestProvider(criteria, false);
Location location = locationManager.getLastKnownLocation(provider);
return location;
}
@Override
protected void onResume() {
super.onResume();
//request to update location every 200 millisecond, and every 1 meter
locationManager.requestLocationUpdates(provider,200, 1, this);
}
/* Remove the locationlistener updates when Activity is paused */
@Override
protected void onPause() {
super.onPause();
locationManager.removeUpdates(this);
}
@Override
public void onLocationChanged(Location location) {
double lat = location.getLatitude();
double lng = location.getLongitude();
Toast.makeText(this, "Location " + lat+","+lng,
Toast.LENGTH_LONG).show();
LatLng coordinate = new LatLng(lat, lng);
Toast.makeText(this, "Location " + coordinate.latitude+","+coordinate.longitude,
Toast.LENGTH_LONG).show();
//remove the marker if exists
if(locationMarker != null)
locationMarker.remove();
//add marker to map
locationMarker = mymap.addMarker(new MarkerOptions()
.position(coordinate)
.title("Are You Spy On Me?")
.snippet("don't expose your position!")
.icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_launcher)));
//going to update the camera with the new coordinates
CameraUpdate center=
CameraUpdateFactory.newLatLng(new LatLng(coordinate.latitude,
coordinate.longitude));
//set camera zoom
CameraUpdate zoom=CameraUpdateFactory.zoomTo(17);
//move camera to location
mymap.moveCamera(center);
mymap.animateCamera(zoom);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.google_map_activity2, menu);
return true;
}
@Override
public void onProviderDisabled(String arg0) {
Toast.makeText(this, "Enabled new provider " + provider,
Toast.LENGTH_SHORT).show();
}
@Override
public void onProviderEnabled(String arg0) {
Toast.makeText(this, "Disabled provider " + provider,
Toast.LENGTH_SHORT).show();
}
@Override
public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
// TODO Auto-generated method stub
}
}
Layout
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
android:id="@+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.SupportMapFragment"
map:cameraTilt="30"
map:cameraZoom="13"
map:mapType="normal"
map:uiCompass="false"
map:uiRotateGestures="true"
map:uiScrollGestures="true"
map:uiTiltGestures="true"
map:uiZoomControls="false"
map:uiZoomGestures="true"/>
Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.urban"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="10" />
<uses-feature
android:glEsVersion="0x00020000"
android:required="true" />
<permission
android:name="com.example.urban.permission.MAPS_RECEIVE"
android:protectionLevel="signature" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="com.example.urban.permission.MAPS_RECEIVE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="your google api key!" />
<uses-library
android:name="com.google.android.maps"
android:required="true" />
<activity
android:name="com.example.urban.GoogleMapActivity2"
android:label="Google Maps Api 2" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.urban"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="10" />
<uses-feature
android:glEsVersion="0x00020000"
android:required="true" />
<permission
android:name="com.example.urban.permission.MAPS_RECEIVE"
android:protectionLevel="signature" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="com.example.urban.permission.MAPS_RECEIVE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="your google api key!" />
<uses-library
android:name="com.google.android.maps"
android:required="true" />
<activity
android:name="com.example.urban.GoogleMapActivity2"
android:label="Google Maps Api 2" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
תוצאה סופית:
סיכום:
עכשיו העולם נראה קטן מתמיד ובעזרת שירותי Google העסק נהפך לפשוט יותר ולא פחות חשוב בחינם, אני לא יודע כמה זמן Google יחליטו להשאיר את השירות חינם עבור משתמשי Android אבל כנראה שכבר לא נלך לאיבוד.
תפסו כיוון!
אין תגובות:
הוסף רשומת תגובה