第五部分 Google地图
本例实现了一个移动版的个人地图。通够MapView来浏览地图程序和使用Location来实现定位功能。
res.layout.main.xml
<?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"
>
<view class="com.google.android.maps.MapView" //在地图开发中只需要一个MapView来显示地图即可,然后加入一些功能菜单,使应用程序更加完美。
在Android中有3种地图模式,所以需要设置一个菜单来切换地图的模式。也可以设置一些城市名字来供用户
选择,如果没有自己要选择的城市,可以设置一个拱用户输入城市名字的输入框。
android:id="@+id/MapView01"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:enabled="true"
android:clickable="true"
android:apiKey="0dYpmIXGIdwiVm-HEpzuUW2fjNYsFQ9EvYir1sg"
/>
</LinearLayout>

res.layout.dialog.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:gravity="center_horizontal"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<TextView
android:id="@+id/TextView01"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<EditText
android:id="@+id/EditText01"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:selectAllOnFocus="true"
android:scrollHorizontally="true"/>
</LinearLayout>

package com.yarin.android.MobileMap;

public class ConstData{
public static final double[][] cityCode ={
{39.930000,116.279998},//北京
{31.399999,121.470001},//上海
{39.099998,117.169998},//天津
{29.520000,106.480003},//重庆
{39.669998,118.150001},//唐山
{38.029998,114.419998},//石家庄
{38.900001,121.629997},//大连
{45.750000,126.769996},//哈尔滨
{20.030000,110.349998},//海口
{43.900001,125.220001},//长春
{28.229999,112.870002},//长沙
{30.670000,104.019996},//成都
{26.079999,119.279998},//福州
{23.129999,113.319999},//广州
{26.579999,106.720001},//贵阳
{30.229999,120.169998},//杭州
{31.870000,117.230003},//合肥
{40.819999,111.680000},//呼和浩特
{36.680000,116.980003},//济南
{25.020000,102.680000},//昆明
{29.657589,911.32050},//拉萨
{36.040000,103.879997},//兰州
{28.600000,115.919998},//南昌
{32.000000,118.800003},//南京
{22.819999,108.349998},//南宁
{36.069999,120.330001},//青岛
{22.549999,114.099998},//深圳
{41.770000,123.430000},//沈阳
{37.779998,112.550003},//太原
{43.779998,87.620002},//乌鲁木齐
{30.620000,114.129997},//武汉
{34.299999,108.930000},//西安
{36.619998,101.769996},//西宁
{24.479999,118.080001},//厦门
{34.279998,117.150001},//徐州
{38.479999,106.220001},//银川
{34.720001,113.650001}//郑州
};
public static final String [] city ={
"北京",//
"上海",//
"天津",//
"重庆",//
"唐山",//
"石家庄",//
"大连",//
"哈尔滨",//
"海口",//
"长春",//
"长沙",//
"成都",//
"福州",//
"广州",//
"贵阳",//
"杭州",//
"合肥",//
"呼和浩特",//
"济南",//
"昆明",//
"拉萨",//
"兰州",//
"南昌",//
"南京",//
"南宁",//
"青岛",//
"深圳",//
"沈阳",//
"太原",//
"乌鲁木齐",//
"武汉",//
"西安",//
"西宁",//
"厦门",//
"徐州",//
"银川",//
"郑州"//
};
}

public class LocationOverlay extends Overlay{//在定位后显示出当前地点的地址以及一个标示,需要使用Overlay来绘制地图上的信息。
private Location mLocation;
private MobileMap mMobileMap;
private String mAddresses;
public LocationOverlay(MobileMap mobileMap){
mMobileMap = mobileMap;
}
public void setLocation(Location location){
mLocation = location;
mAddresses = getAddresses();
}
public boolean draw(Canvas canvas, MapView mapView, boolean shadow, long when){//要在MapView上绘制信息,需要重写Overlay的Draw方法,绘制方法和一般绘图一样
super.draw(canvas, mapView, shadow);
Paint paint = new Paint();
Point scPoint = new Point();
GeoPoint tmpGeoPoint = new GeoPoint((int)(mLocation.getLatitude()*1E6),(int)(mLocation.getLongitude()*1E6));
mapView.getProjection().toPixels(tmpGeoPoint, scPoint);//通过toPixels方法将经度和纬度的信息转换成屏幕上对象的像素坐标信息。

paint.setStrokeWidth(1);
paint.setARGB(255, 255, 0, 0);
paint.setStyle(Paint.Style.STROKE);
paint.setFlags(Paint.ANTI_ALIAS_FLAG);//消除字体的锯齿效果
paint.setTextSize(16);

Bitmap bmp = BitmapFactory.decodeResource(mMobileMap.getResources(), R.drawable.mark);
canvas.drawBitmap(bmp, scPoint.x-bmp.getWidth()/2, scPoint.y-bmp.getHeight(), paint);
canvas.drawText(mAddresses, scPoint.x-paint.measureText(mAddresses)/2, scPoint.y, paint);
return true;
}
public String getAddresses(){
String addressString="没有找到地址";
Geocoder gc=new Geocoder(mMobileMap,Locale.getDefault());
try{
List<Address> addresses=gc.getFromLocation(mLocation.getLatitude(), mLocation.getLongitude(),1);//在绘制之前需要得到当前地点的地址信息,
Geocoder为我们提供了getFromLocation方法来获得地址等信息。
StringBuilder sb=new StringBuilder();
if(addresses.size()>0){
Address address = addresses.get(0);
sb.append("地址:");
for (int i = 0; i < address.getMaxAddressLineIndex(); i++){
sb.append(address.getAddressLine(i));
}
addressString=sb.toString();
}
}catch(IOException e){
}
return addressString;
}
}

public class MobileMap extends MapActivity{//MapActivity用于浏览地图,定位信息处理以及一些菜单事件的处理,我们程序中定义了一些城市的名字供用户选择,在
选择之后将通过该城市所对应的经度和纬度的数据来进行定位。当用户输入城市名字的时候,可以通过Geocoder.getFromLocationName
方法将名字转换成地址,然后找到最合适的城市进行定位
private MapViewmMapView;
private MapControllermMapController;
private GeocodermGeocoder;
private LocationOverlaymLocationOverlay;
private LocationManager mlocationManager;
private Location mLocation;

private static final intSearch= Menu.FIRST;
private static final intSelectCity= Menu.FIRST + 1;
private static final intViewMode= Menu.FIRST + 2;
private static final intExit= Menu.FIRST + 3;

public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
init();
}
protected boolean isRouteDisplayed(){
return false;
}
public void init(){
mMapView=(MapView)findViewById(R.id.MapView01);
mMapController=mMapView.getController(); //取得MapController实例,控制地图
mlocationManager=(LocationManager)getSystemService(Context.LOCATION_SERVICE);
mMapView.setEnabled(true);
mMapView.setClickable(true);
mMapView.setTraffic(false);//设置显示模式
mMapView.setSatellite(false);
mMapView.setStreetView(true);
mMapView.setBuiltInZoomControls(true); //设置缩放
mMapController.setZoom(12);//设置地图等级

mLocationOverlay=new LocationOverlay(this);
List<Overlay> overlays=mMapView.getOverlays();
overlays.add(mLocationOverlay);

Criteria criteria =new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE); //经度要求
criteria.setAltitudeRequired(false);
criteria.setBearingRequired(false);
criteria.setCostAllowed(false);
criteria.setPowerRequirement(Criteria.POWER_LOW);

String provider=mlocationManager.getBestProvider(criteria, true);//取得效果最好的criteria
mLocation=mlocationManager.getLastKnownLocation(provider); //得到坐标相关的信息
mGeocoder = new Geocoder(this,Locale.getDefault());
updateLocation(mLocation);
mlocationManager.requestLocationUpdates(provider, 3000, 0,mLocationListener);
}
public void updateLocation(Location location) {//更新定位
if ( location == null ){
return;
}
mLocationOverlay.setLocation(location);
Double geoLat=location.getLatitude()*1E6;
Double geoLng=location.getLongitude()*1E6;
GeoPoint point=new GeoPoint(geoLat.intValue(),geoLng.intValue()); //将其转换为int型
mMapController.animateTo(point); //定位到指定坐标
}
public MapController getMapController(){
return mMapController;
}
private final LocationListener mLocationListener=new LocationListener(){
public void onLocationChanged(Location location){
updateLocation(location);
}
public void onProviderDisabled(String provider){
}
public void onProviderEnabled(String provider){
}
public void onStatusChanged(String provider,int status,Bundle extras){
}
};
public boolean onCreateOptionsMenu(Menu menu){
super.onCreateOptionsMenu(menu);
menu.add(0, Search, Menu.NONE, "搜索地点").setIcon(R.drawable.search);
menu.add(0, SelectCity, Menu.NONE, "选择城市").setIcon(R.drawable.selectcity);
menu.add(0, ViewMode, Menu.NONE, "地图模式").setIcon(R.drawable.viewmode);
menu.add(0, Exit, Menu.NONE, "退出").setIcon(R.drawable.exit);
return true;
}
public boolean onOptionsItemSelected(MenuItem item){
super.onOptionsItemSelected(item);
switch (item.getItemId()){
case Search:
searchCity();
return true;
case SelectCity:
selectCity();
return true;
case ViewMode:
selectViewMode();
return true;
case Exit:
this.finish();
return true;
}
return true;
}
public void selectCity(){ //选择城市
OnClickListener listener = new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which){
Double geoLat=ConstData.cityCode[which][0]*1E6;
Double geoLng=ConstData.cityCode[which][1]*1E6;

mLocation.setLatitude(ConstData.cityCode[which][0]);
mLocation.setLongitude(ConstData.cityCode[which][1]);
mLocationOverlay.setLocation(mLocation);
GeoPoint point=new GeoPoint(geoLat.intValue(),geoLng.intValue());
mMapController.animateTo(point);//定位到指定坐标
}
};
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, ConstData.city);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
new AlertDialog.Builder(MobileMap.this)
.setTitle("请选择城市")
.setAdapter(adapter, listener)
.show();
}
public void selectViewMode(){ //选择地图模式
OnClickListener listener = new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which){
switch ( which ){
case 0:
mMapView.setTraffic(false);
mMapView.setSatellite(false);
mMapView.setStreetView(true);
break;
case 1:
mMapView.setSatellite(false);
mMapView.setStreetView(false);
mMapView.setTraffic(true);
break;
case 2:
mMapView.setStreetView(false);
mMapView.setTraffic(false);
mMapView.setSatellite(true);
break;
}
}
};
String[] menu={"街景模式","交通流量","卫星地图"};
new AlertDialog.Builder(MobileMap.this)
.setTitle("请选择地图模式")
.setItems(menu, listener)
.show();
}
public void searchCity(){ //搜索城市
//自定义一个带输入的对话框由TextView和EditText构成
final LayoutInflater factory = LayoutInflater.from(MobileMap.this);
final View dialogview = factory.inflate(R.layout.dialog, null);
((TextView) dialogview.findViewById(R.id.TextView01)).setText("搜索地图");//设置TextView的提示信息
((EditText) dialogview.findViewById(R.id.EditText01)).setText("请输入要查找的地址...");//设置EditText输入框初始值
Builder builder = new Builder(MobileMap.this);
builder.setTitle("请输入地名");
builder.setView(dialogview);
builder.setPositiveButton(android.R.string.ok,new AlertDialog.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
String value = ((EditText) dialogview.findViewById(R.id.EditText01)).getText().toString().trim();//点击确定之后
if ( value != "" ){
searchName(value);
}
}
});
builder.setNegativeButton(android.R.string.cancel,new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
public void onCancel(DialogInterface dialog) {
dialog.cancel();
}
});
builder.show();
}
public void searchName(String nameStr){
try{
List<Address> addresses = mGeocoder.getFromLocationName(nameStr, 1);
if (addresses.size() != 0){
Address address = addresses.get(0);
GeoPoint geoPoint = new GeoPoint((int) (address.getLatitude() * 1E6), (int) (address.getLongitude() * 1E6));
mLocation.setLatitude(address.getLatitude());
mLocation.setLongitude(address.getLongitude());
mLocationOverlay.setLocation(mLocation);
mMapController.animateTo(geoPoint);
}
}
catch (IOException e){}
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.yarin.android.MobileMap"
android:versionCode="1"
android:versionName="1.0">
<application
android:icon="@drawable/icon"
android:label="@string/app_name">
<uses-library android:name="com.google.android.maps" />
<activity
android:name=".MobileMap"
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>//因为使用了com.google.android.maps所以需要声明权限。如果要发布应用程序需要申请Google的API Key
<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-sdk android:minSdkVersion="5" />
</manifest>

更多相关文章

  1. Android获得Location信息的方法
  2. Android(安卓)APP - GPS定位并获取地理位置
  3. android 使用Google地图步骤要点
  4. Android(安卓)Studio基本常用快捷键
  5. 简单好用的控件源码
  6. android 地图服务开发 INSTALL_FAILED_MISSING_SHARED_LIBRARY
  7. Android(安卓)地图 —— 百度地图
  8. Android(安卓)客服端集成高德定位功能(Android(安卓)studio图文详
  9. 关于Android中的Parcel机制

随机推荐

  1. Android布局及控件的属性说明
  2. Android深入浅出之Surface
  3. android如何读取assets目录下的资源
  4. android整合两个bitmap
  5. Android(安卓)删除手机联系人,添加手机联
  6. android TextView 容纳不下内容,让字向左
  7. 关于android多点触控
  8. android 主activity 设置
  9. Android(安卓)使用RecyclerView的方法
  10. 抽离Android原生控件的方法