Android Google Maps 完整实例分析

 第五部分 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 MapView   mMapView;
     private MapController mMapController;
     private Geocoder  mGeocoder;
     private LocationOverlay mLocationOverlay;
     private LocationManager mlocationManager;
     private Location mLocation;

     private static final int Search  = Menu.FIRST;
     private static final int SelectCity = Menu.FIRST + 1;
     private static final int ViewMode = Menu.FIRST + 2;
     private static final int Exit  = 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>

你可能感兴趣的:(android,String,Google,layout,dialog,encoding)