安卓---高德地图API应用
说明:定位需要导入android_location 的jar包,如果没有会报错,这个官方网站好像找不到,这是我在网上找到的一个链接
http://download.csdn.net/detail/raindays1/9469464
导航和路线规划写在我另一篇博客:http://www.cnblogs.com/rainday1/p/5550857.html
现在的地图接口更新太快,本人才接触安卓没多久,对于地图的应用还不能随机应变。刚开始本来想用百度地图的API,可是一直报错,网上也没找到合适的解决方法,一气之下把原来的工程删除了,转手高德地图,都说高德有详细的开发文档,但是更新后的高德也和开发文档有些许出入。参照着http://www.cnblogs.com/ouyangduoduo/p/4619407.html博客把最基本的地图层显示出来了。
关于申请高德地图API Key的步骤我这里不做详细介绍,官方网上有说明。直接应用显示地图,新建工程导入jar包,方法在我上一片博客中有图文说明,这里就直接省略
把从官网上下载的文件解压到自己的电脑,然后把文件包里面的东西都拷到工程中去(2.0之后不需要单独导入Locationjar包)
1.
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<meta-data
android:name="com.amap.api.v2.apikey"
android:value="自己的key"/>
<!--<service android:name="com.amap.api.location.APSService"></service>2.0之前不需要,2.0之后定位必须加上-->
<activity
android:name="com.example.bmap.MainActivity"
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>
2.
android 高德地图定位服务启动失败,此为定位需要的服务,使用2.0以上的定位就需要这个。2.0之后不需要单独导入定位包
在官方提供的demo中其实就已经写到了,只是新手一般在添加权限之后就不太会注意到AndroidManifest中的此点。
加上之后定位功能就可以实现了
在AndroidManifest中添加,如上面标红的地方
<service android:name="com.amap.api.location.APSService"></service>
<!-- //地图包、搜索包需要的基础权限 --> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <!-- 定位包、导航包需要的额外权限(注:基础权限也需要) --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" /> <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
3.布局文件activity_main.xml中添加map控件
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <!-- 引入布局文件 --> <com.amap.api.maps.MapView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/location" android:layout_width="match_parent" android:layout_height="match_parent" /> </RelativeLayout>
4. 主函数
package com.example.bmap; import android.app.Activity; import android.os.Bundle; import com.amap.api.maps.AMap; import com.amap.api.maps.MapView; public class MainActivity extends Activity { private MapView mapView; private AMap aMap; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mapView = (MapView) findViewById(R.id.location); mapView.onCreate(savedInstanceState);//必须要写 init(); //夜景模式 //aMap.setMapType(AMap.MAP_TYPE_NIGHT);
//显示交通图 //aMap.setTrafficEnabled(true); } /** * 初始化AMap对象 */ private void init() { if (aMap == null) { aMap = mapView.getMap(); } } /** * 方法必须重写 */ @Override protected void onResume() { super.onResume(); mapView.onResume(); } /** * 方法必须重写 */ @Override protected void onPause() { super.onPause(); mapView.onPause(); } /** * 方法必须重写 */ @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); mapView.onSaveInstanceState(outState); } /** * 方法必须重写 */ @Override protected void onDestroy() { super.onDestroy(); mapView.onDestroy(); } }
到这里,简单的地图就做出来了,运行一下吧。
下面我们在地图上添加定位和天气信息,以及跟随/定位/旋转
定位需要导入android_location 的jar包,如果没有会报错,这个官方网站好像找不到,这是我在网上找到的一个链接
http://download.csdn.net/detail/raindays1/9469464
导入jar包的方法在我上一片博客中有图文说明,这里就直接省略
1.AndroidManifest.xml文件里的设置和上面的例子里面一样,复制下来即可,
2.布局文件activity.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <!-- 引入布局文件 --> <com.amap.api.maps.MapView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/location" android:layout_width="match_parent" android:layout_height="match_parent" > </com.amap.api.maps.MapView> <TextView android:id="@+id/tv_weather" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_alignLeft="@+id/gps_radio_group" android:layout_alignParentTop="true" android:textColor="@android:color/black" android:textSize="28sp" /> <RadioGroup android:id="@+id/gps_radio_group" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|left" android:layout_marginLeft="10dp" android:layout_marginTop="10dp" android:background="#00101010"<!--前两位是代表透明度,后面代表背景颜色--> android:orientation="horizontal" > <RadioButton android:id="@+id/gps_locate_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:checked="true" android:text="定位" <!--这个颜色要求最低 android:minSdkVersion="14"--> android:textColor="@android:color/holo_red_light" /> <RadioButton android:id="@+id/gps_follow_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="跟随" android:textColor="@android:color/holo_red_light" /> <RadioButton android:id="@+id/gps_rotate_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="旋转" android:textColor="@android:color/holo_red_light" /> </RadioGroup> </RelativeLayout>
3.主函数
package com.example.bmap; import java.util.List; import android.app.Activity; import android.location.Location; import android.os.Bundle; import android.util.Log; import android.widget.RadioGroup; import android.widget.RadioGroup.OnCheckedChangeListener; import android.widget.TextView; import android.widget.Toast; import com.amap.api.location.AMapLocalDayWeatherForecast; import com.amap.api.location.AMapLocalWeatherForecast; import com.amap.api.location.AMapLocalWeatherListener; import com.amap.api.location.AMapLocalWeatherLive; import com.amap.api.location.AMapLocation; import com.amap.api.location.AMapLocationListener; import com.amap.api.location.LocationManagerProxy; import com.amap.api.location.LocationProviderProxy; import com.amap.api.maps.AMap; import com.amap.api.maps.LocationSource; import com.amap.api.maps.MapView; public class MainActivity extends Activity implements LocationSource, AMapLocationListener,AMapLocalWeatherListener, OnCheckedChangeListener { private MapView mapView; private AMap aMap; private LocationManagerProxy mLocationManagerProxy; private OnLocationChangedListener mListener; private RadioGroup mGPSModeGroup; private static final String TAG = "LocationActivity"; private TextView tvWeather; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mapView = (MapView) findViewById(R.id.location); tvWeather = (TextView) findViewById(R.id.tv_weather); mapView.onCreate(savedInstanceState);//必须要写 init(); //夜景模式 //aMap.setMapType(AMap.MAP_TYPE_NIGHT); aMap.setTrafficEnabled(true); } /** * 初始化AMap对象 */ private void init() { if (aMap == null) { aMap = mapView.getMap(); } mGPSModeGroup = (RadioGroup) findViewById(R.id.gps_radio_group); mGPSModeGroup.setOnCheckedChangeListener(this); initLocation(); setUpMap(); } @Override public void onCheckedChanged(RadioGroup group, int checkedId) { switch (checkedId) { case R.id.gps_locate_button: // 设置定位的类型为定位模式 aMap.setMyLocationType(AMap.LOCATION_TYPE_LOCATE); break; case R.id.gps_follow_button: // 设置定位的类型为 跟随模式 aMap.setMyLocationType(AMap.LOCATION_TYPE_MAP_FOLLOW); break; case R.id.gps_rotate_button: // 设置定位的类型为根据地图面向方向旋转 aMap.setMyLocationType(AMap.LOCATION_TYPE_MAP_ROTATE); break; } } /** * 初始化定位 * 初始化天气 */ private void initLocation(){ mLocationManagerProxy = LocationManagerProxy.getInstance(this); //此方法为每隔固定时间会发起一次定位请求,为了减少电量消耗或网络流量消耗, //注意设置合适的定位时间的间隔,并且在合适时间调用removeUpdates()方法来取消定位请求 //在定位结束后,在合适的生命周期调用destroy()方法 //其中如果间隔时间为-1,则定位只定一次 mLocationManagerProxy.requestLocationData( LocationProviderProxy.AMapNetwork, -1, 15, this); //天气请求 mLocationManagerProxy.requestWeatherUpdates( LocationManagerProxy.WEATHER_TYPE_FORECAST, this); mLocationManagerProxy.setGpsEnable(false); } @Override public void onWeatherForecaseSearched(AMapLocalWeatherForecast aMapLocalWeatherForecast) { // TODO Auto-generated method stub if(aMapLocalWeatherForecast != null && aMapLocalWeatherForecast.getAMapException().getErrorCode() == 0){ List<AMapLocalDayWeatherForecast> forcasts = aMapLocalWeatherForecast .getWeatherForecast(); for (int i = 0; i < forcasts.size(); i++) { AMapLocalDayWeatherForecast forcast = forcasts.get(i); switch (i) { //今天天气 case 0: //城市 String city = forcast.getCity(); String today = "今天 ( "+ forcast.getDate() + " )"; String todayWeather = forcast.getDayWeather() + " " + forcast.getDayTemp() + "/" + forcast.getNightTemp() + " " + forcast.getDayWindPower(); tvWeather.setText("城市:" + city + ", " + today + ", 天气信息:" + todayWeather); break; //明天天气 case 1: String tomorrow = "明天 ( "+ forcast.getDate() + " )"; String tomorrowWeather = forcast.getDayWeather() + " " + forcast.getDayTemp() + "/" + forcast.getNightTemp() + " " + forcast.getDayWindPower(); tvWeather.append("; " + tomorrow + ", 天气信息:" + tomorrowWeather); break; //后天天气 case 2: String aftertomorrow = "后天( "+ forcast.getDate() + " )"; String aftertomorrowWeather = forcast.getDayWeather() + " " + forcast.getDayTemp() + "/" + forcast.getNightTemp() + " " + forcast.getDayWindPower(); tvWeather.append("; " + aftertomorrow + ", 天气信息:" + aftertomorrowWeather); break; } } }else{ // 获取天气预报失败 Toast.makeText(this,"获取天气预报失败:"+ aMapLocalWeatherForecast.getAMapException().getErrorMessage(), Toast.LENGTH_SHORT).show(); } } private void setUpMap(){ aMap.setLocationSource(this);// 设置定位监听 aMap.getUiSettings().setMyLocationButtonEnabled(true);// 设置默认定位按钮是否显示 aMap.setMyLocationEnabled(true);// 设置为true表示显示定位层并可触发定位,false表示隐藏定位层并不可触发定位,默认是false // 设置定位的类型为定位模式:定位(AMap.LOCATION_TYPE_LOCATE)、跟随(AMap.LOCATION_TYPE_MAP_FOLLOW) // 地图根据面向方向旋转(AMap.LOCATION_TYPE_MAP_ROTATE)三种模式 aMap.setMyLocationType(AMap.LOCATION_TYPE_LOCATE); } /** * 激活定位 */ @Override public void activate(OnLocationChangedListener onLocationChangedListener) { // TODO Auto-generated method stub mListener = onLocationChangedListener; if (mLocationManagerProxy == null) { mLocationManagerProxy = LocationManagerProxy.getInstance(this); //此方法为每隔固定时间会发起一次定位请求,为了减少电量消耗或网络流量消耗, //注意设置合适的定位时间的间隔,并且在合适时间调用removeUpdates()方法来取消定位请求 //在定位结束后,在合适的生命周期调用destroy()方法 //其中如果间隔时间为-1,则定位只定一次 mLocationManagerProxy.requestLocationData( LocationProviderProxy.AMapNetwork, -1, 10, this); } } /** * 停止定位 */ @Override public void deactivate() { // TODO Auto-generated method stub mListener = null; if (mLocationManagerProxy != null) { mLocationManagerProxy.removeUpdates(this); mLocationManagerProxy.destroy(); } mLocationManagerProxy = null; } /** * 方法必须重写 */ @Override protected void onResume() { super.onResume(); mapView.onResume(); } /** * 方法必须重写 */ @Override protected void onPause() { super.onPause(); mapView.onPause(); deactivate(); } /** * 方法必须重写 */ @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); mapView.onSaveInstanceState(outState); } /** * 方法必须重写 */ @Override protected void onDestroy() { super.onDestroy(); mapView.onDestroy(); } @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 } @Override public void onLocationChanged(AMapLocation aMapLocation) { // TODO Auto-generated method stub if(aMapLocation != null && aMapLocation.getAMapException().getErrorCode() == 0){ //获取位置信息 Double geoLat = aMapLocation.getLatitude(); Double geoLng = aMapLocation.getLongitude(); Log.d(TAG, "Latitude = " + geoLat.doubleValue() + ", Longitude = " + geoLng.doubleValue()); // 通过 AMapLocation.getExtras() 方法获取位置的描述信息,包括省、市、区以及街道信息,并以空格分隔。 String desc = ""; Bundle locBundle = aMapLocation.getExtras(); if (locBundle != null) { desc = locBundle.getString("desc"); Log.d(TAG, "desc = " + desc); } mListener.onLocationChanged(aMapLocation);// 显示系统小蓝点 } } @Override public void onWeatherLiveSearched(AMapLocalWeatherLive arg0) { // TODO Auto-generated method stub } }
运行结果如下:旋转的时候我的模拟器会停止运行,没让显示全就急忙截图了