1 Maps API Key申请
要使用Google提供的map服务,必须先申请一个Maps API Key。步骤如下:
Step1:申请MD5
(1)打开eclipse,然后选择Window-->Preferences-->Android-->Build,这时候我们可以查找debug.keystore的路径,如下图:
(2)将debug.keystore拷贝到keytool所在目录,如果安装JDK是按默认路径安装,keytool是在C:\Program Files\Java\jdk1.6.0_25\bin下。
(3)运行cmd,进入到keytool的目录下,输入 keytool -list -keystore debug.keystore,提示输入密码时直接回车,得到MD5。
Step2:利用MD5申请API Key。
登陆http://code.google.com/intl/zh-CN/android/maps-api-signup.html,输入获取的MD5,Generate API Key即可(需要gmail邮箱)。
注:申请API Key的官网文档见http://code.google.com/intl/zh-CN/android/add-ons/google-apis/mapkey.html
2 Maps开发
Map开发最好的学习资料:
(1)http://developer.android.com/guide/tutorials/views/hello-mapview.html
(2)Demo:<sdk>/add-ons/google_apis-<api-level>/samples/MapsDemo
(3)
Package com.google.android.maps (<sdk>/add-ons/google_apis-<api-level>/docs/reference/index.html)
2.1 建立工程
Android maps开发建立工程时需要选择Google API,如果没有相应版本的Google API,打开Windows>Android SDK and AVD Manager>Available package里面下载相应的add-ons,如下图:
下载完成后,在android-sdk-windows\add-ons\addon_google_apis_google_inc_10\docs\reference\index.html里面查阅map相关的API,也可以在官网(http://code.google.com/intl/zh-CN/android/add-ons/google-apis/reference/com/google/android/maps/package-summary.html)上查询。
2.2 编写mapView.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/mainlayout" 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:clickable="true" android:apiKey="Your Maps API Key" /> </RelativeLayout>
2.3 添加mapActivity
public class MappingOverlayActivity extends MapActivity {
private MapView mapView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
@Override
protected boolean isLocationDisplayed() {
return false;
}
}
2.4 AndroidManifest.xml
(1)application element里面添加uses-library
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.package.name">
...
<application android:name="MyApplication" >
<uses-library android:name="com.google.android.maps" />
...
</application>
(2)添加网络权限
<uses-permission android:name="android.permission.INTERNET" />
3 Location
Android gives your applications access to the location services supported by the device through the classes in the android.location package. The central component of the location framework is the LocationManager system service, which provides APIs to determine location and bearing of the underlying device (if available).
As with other system services, you do not instantiate a LocationManager directly. Rather, you request an instance from the system by calling getSystemService(Context.LOCATION_SERVICE). The method returns a handle to a new LocationManager.
Location相关的最关键的三个class是:LocationManager,LocationListener,LocationProvider.具体内容请查阅SDK文档。另外Geocoder里面有曾经令人鸡动的API,但是暂时还无法获得服务(The Geocoder class requires a backend service that is not included in the core android framework. The Geocoder query methods will return an empty list if there no backend service in the platform. Use the isPresent() method to determine whether a Geocoder implementation exists.)。
3.1 获取当前位置信息
LocationManager locMan = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
Location location = locMan.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if(null == location){
location = locMan.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
}
注:此处只是为了比较清晰的说明如何使用Location Service,事实上这样做getLastKnownLocation的返回值为null,解决方法见5.1.
3.2 监听位置变化
(1)实例化LocationListener
LocationListener mLocationListener1 = new LocationListener() {
@Override
public void onLocationChanged(Location location) {}
@Override
public void onProviderDisabled(String provider) {}
@Override
public void onProviderEnabled(String provider) {}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {}
};
(2)注册监听
locMan.requestLocationUpdates(LocationManager.GPS_PROVIDER, 60000, 1, mLocationListener1);//激活LocationListener对象mLocationListener1
(3)注销监听
locMan.removeUpdates(mLocationListener1);
4 Search
在地图开发中经常会用到搜索地名,android作为Google的产品,自然对搜索支持得很好。Search应用开发最好的资料见http://developer.android.com/guide/topics/search/index.html (或者android-sdk-windows\docs\guide\index.html>Dev Guide>Search)
Search分两部分,是一个C/S架构。Client负责发起搜索,有search view和search dialogue两种方式;server端负责接收搜索请求,进行搜索。
4.1 Search Server(Searchable Activity)
(1)创建Searchable的xml配置文件,这个配置文件通常命名为searchable.xml,并放置在
res/xml/目录下
.
<?xml version="1.0" encoding="utf-8"?> <searchable xmlns:android="http://schemas.android.com/apk/res/android" android:label="@string/app_label" android:hint="@string/search_hint" > </searchable>
android:label是唯一一个必须写明的属性,其余可选。
(2)创建Searchable Activity,用以响应search请求,执行搜索动作。
Searchabel Activity的source code:
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.search); // Get the intent, verify the action and get the query Intent intent = getIntent(); if (Intent.ACTION_SEARCH.equals(intent.getAction())) { String query = intent.getStringExtra(SearchManager.QUERY); doMySearch(query); } }
Searchabel Activity在AndroidManifest.xml里面的声明):
<application ... > <activity android:name=".SearchableActivity" > <intent-filter> <action android:name="android.intent.action.SEARCH" /> </intent-filter> <meta-data android:name="android.app.searchable" android:resource="@xml/searchable"/> </activity> ... </application>
4.2 Search Client(发起搜索请求的activity,此处命名为ClientActivity)
(1)在AndroidManifest.xml里面声明clientActivity,并添加搜索属性
<application ... >
<!-- this activity enables the search dialog to initiate searches in the SearchableActivity -->
<activity android:name=".ClientActivity" ... >
<!-- enable the search dialog to send searches to SearchableActivity -->
<meta-data android:name="android.app.default_searchable"
android:value=".SearchableActivity" />
</activity>
...
</application>
(2)在ClientActivity里面,有2种请求搜索的方法,Search Dialog和Search View。
5 问题汇总及解决办法
5.1 getLastKnownLocation returns null
1 AndroidManifest.xml里添加权限
<manifest ... > <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.INTERNET" /> ... </manifest>
2 源码(如果在室内,注意不要使用GPS Provider)
LocationManager mgr = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Location location = mgr.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
while(location == null)
{
mgr.requestLocationUpdates("gps", 60000, 1, locationListener);
}
5.2 onLocationChanged never triggered
1 如果在室内,使用NETWORK_PROVIDER,不要使用GPS_PROVIDER.
2 如果在模拟器上调试,在setting>data&time里面把时间修改正确。
5.3 geoCoder.getFromLocationName returns null
参考http://blog.csdn.net/evanwu_85/article/details/6544325
5.4 debug.keystore过期
如果debug.keystore过期或更换(比如更换电脑),Map APIKey需要重新生成MD5去申请。
注:删除过期的debug.store,系统会自动重新生成一个新的debug.store文件。
6 Reference
Google Projects for Android
http://developer.android.com/guide/topics/location/index.html (或者android-sdk-windows\docs\guide\index.html>Dev Guide>Location and Maps)
http://developer.android.com/guide/topics/search/index.html (或者android-sdk-windows\docs\guide\index.html>Dev Guide>Search)