android map 标示

2024-02-05 18:58
文章标签 android map 标示

本文主要是介绍android map 标示,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

2010 Andriod篇做了一个小应用智能情景的切换,这个应用是学习android开发以来应用类开发的比较满意的一个。虽然它只有一个view 一个activity,但是却囊括了android的很多特性。借此机会,和大家分享一下这个小应用。

先上截图:
c63148cc-5cfd-312a-a248-fcf75c3a4ce0.png 


应用的主要功能是根据适当的情景(如地点,手机状态等)为用户自动的切换情景模式。
比方说:手机向上是铃音+震动,当开会时,将手机翻转,将自动切换成静音模式。
还可以根据经纬度,到达一个地方后自动切换成用户预先设置的情景模式。
(当然,由于没找到合适的经纬度换算工具,经纬度的判断目前只能是精确位置,不是范围值。
因此只能算是个学习的小应用了,实际的应用还有待完善啊。如果有高手知道的话,麻烦告诉我下。万分感谢)

-------------------------废话不多说开始代码部分-----------------------------------------------------
虽然是一个只有一个页面的小应用,但是
麻雀虽小,五脏俱全
这个应用的功能点主要有:
     改变情景模式
     实时获取地理位置
     实时判断手机重力状态
用到的技术包括:
1.android Google map的应用
2.Android组件的使用    Activity(MapActivity)    Service    Broadcastreceiver
3.Xml解析4.文件存储5.传感器使用6.底层绘图7.自定义view

由于使回头看代码,我就从简单的部分一步步介绍。

首先是权限问题,很多新手都犯了这个毛病,程序出错,往往是权限没有添加。
Java代码
  1. <!-- 网络链接 -->   
  2.    <uses-permission android:name="android.permission.INTERNET"/>   
  3.    <!-- 地图 -->   
  4.    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>   
  5.    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>   
  6.    <!-- 读写权限 -->   
  7.    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />   
  8.    <uses-permission android:name="android.permission.WRITE" />  
复制代码

这个应用需要网络连接的权限,因为Google  map是实时更新的么。然后是GPS传感器关于地理位置的权限。最后需要存储用户的记录点,所以有文件读写的权限。

为了记录用户记录的情景地点,我使用了XML作为存储的标准,并将文件存在了SD卡上
XML解析
网络上有很详细的各种解析方式,我采用了其中的一种。如果想了解其他的请Google。。。。。
记录地点信息,我定义了一个POJO类
Java代码

  1. public class RecordLocation {   
  2.     private String location_Id;   
  3.     private String location_ring;   
  4.     private double location_latitude;   
  5.     private double location_longitude;   
  6.     private GeoPoint    point;   
  7. ...篇幅关系,其他的略  
复制代码

XML的解析器,和网络上的其他文章一样就不多说了。能拿来用就成。
Java代码

  1. public List<RecordLocation> parse(String xml) {   
  2.         final RecordLocation currentMessage = new RecordLocation();   
  3.         RootElement root = new RootElement("Locations");   
  4.         final List<RecordLocation> messages = new ArrayList<RecordLocation>();   
  5.        // Element channel = root.getChild("RespInfo");  
  6.         Element item = root.getChild("Location");   
  7.         item.setEndElementListener(new EndElementListener(){   
  8.             public void end() {   
  9.                 messages.add(currentMessage.copy());   
  10.             }   
  11.         });   
  12.         item.getChild("id").setEndTextElementListener(new EndTextElementListener(){   
  13.             public void end(String body) {   
  14.                 currentMessage.setLocation_Id(body);   
  15.             }   
  16.         });   
  17.         item.getChild("ring").setEndTextElementListener(new EndTextElementListener(){   
  18.             public void end(String body) {   
  19.                 currentMessage.setLocation_ring(body);   
  20.             }   
  21.         });   
  22.         item.getChild("latitude").setEndTextElementListener(new  
  23.           EndTextElementListener(){   
  24.             public void end(String body) {   
  25.                 currentMessage.setLocation_latitude(Double.valueOf(body));   
  26.             }   
  27.         });   
  28.         item.getChild("longitude").setEndTextElementListener(new EndTextElementListener(){   
  29.             public void end(String body) {   
  30.                 currentMessage.setLocation_longitude(Double.valueOf(body));   
  31.             }   
  32.         });   

  33.         try {   
  34.             InputStream   inputStream   =   new   ByteArrayInputStream(xml.getBytes());   
  35.             Xml.parse(inputStream, Xml.Encoding.UTF_8,   
  36.             root.getContentHandler());   
  37.         } catch (Exception e) {   
  38.             throw new RuntimeException(e);   
  39.         }   
  40.         return messages;   
  41.     }  
复制代码

POJO类转化成XML字符串
Java代码

  1. public static String writeXml(List<RecordLocation> data){   
  2.         XmlSerializer serializer = Xml.newSerializer();   
  3.         StringWriter writer = new StringWriter();   
  4.         try{   
  5.             serializer.setOutput(writer);   
  6.             // <?xml version=”1.0″ encoding=”UTF-8″ standalone=”yes”?>  
  7.             serializer.startDocument("UTF-8",true);   
  8.             serializer.startTag("","Locations");   

  9.             for(int i=0;i<data.size();i++){   
  10.                 serializer.startTag("","Location");   

  11.                 serializer.startTag("","id");   
  12.                 serializer.text(data.get(i).getLocation_Id());   
  13.                 serializer.endTag("","id");   

  14.                 serializer.startTag("","ring");   
  15.                 serializer.text(data.get(i).getLocation_ring());   
  16.                 serializer.endTag("","ring");   

  17.                 serializer.startTag("","latitude");   
  18.                 serializer.text(String.valueOf(data.get(i).getLocation_latitude()));   
  19.                 serializer.endTag("","latitude");   

  20.                 serializer.startTag("","longitude");   
  21.                 serializer.text(String.valueOf(data.get(i).getLocation_longitude()));   
  22.                 serializer.endTag("","longitude");   

  23.                 serializer.endTag("","Location");   

  24.             }   


  25.             serializer.endTag("","Locations");   
  26.             serializer.endDocument();   
  27.             return writer.toString();   
  28.         }   
  29.         catch(Exception e)   
  30.         {   
  31.             throw new RuntimeException(e);   
  32.         }   
  33.     }  
复制代码

有了XML的字符串后只要将它存储起来就行,需要使用是再读取
以下是存储和读取文件函数。由于SD卡的读取还需要判断SD卡的状态,函数比较长,就贴存手机内存的代码
反正大同小异
Java代码

  1. public static InputStream readInternalFileInputStream(Context context,String fileName){   
  2.         /** 
  3.          * 读取手机内存文件 
  4.          * */  

  5.         try{   
  6.             FileInputStream fis = context.openFileInput(fileName);   

  7.             return fis;   
  8.         }catch(Exception e){   
  9.             return null;   
  10.         }   

  11.     }   
  12.     public static String readInternalFile(Context context,String fileName){   
  13.         /** 
  14.          * 读取手机内存文件 
  15.          * */  

  16.         try{   
  17.             byte[] buffer = new byte[512];   
  18.             int read =0;   
  19.             StringBuffer stringbuffer = new StringBuffer();   
  20.             FileInputStream fis = context.openFileInput(fileName);   
  21.             do{   
  22.                 read = fis.read(buffer);   
  23.                 if(read>0)   
  24.                    stringbuffer.append(new String(buffer, 0, read, "utf-8"));   

  25.             }while(read!=-1);   
  26.             fis.close();   
  27.             return stringbuffer.toString();   
  28.         }catch(Exception e){   
  29.             return null;   
  30.         }   

  31.     }  
复制代码



数据存储部分完毕了。接下来是关于切换手机情景的功能

手机的铃音设置
Java代码

  1. AudioManager audio = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);   

  2. // 铃声和震动  
  3.     protected void ringAndVibrate(AudioManager audio){   
  4.         audio.setRingerMode(AudioManager.RINGER_MODE_NORMAL);   
  5.         audio.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER, AudioManager.VIBRATE_SETTING_ON);   
  6.         audio.setVibrateSetting(AudioManager.VIBRATE_TYPE_NOTIFICATION, AudioManager.VIBRATE_SETTING_ON);   
  7.     }   
  8.     // 铃声  
  9.     protected void ring(AudioManager audio){   
  10.         audio.setRingerMode(AudioManager.RINGER_MODE_NORMAL);   
  11.         audio.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER, AudioManager.VIBRATE_SETTING_OFF);   
  12.         audio.setVibrateSetting(AudioManager.VIBRATE_TYPE_NOTIFICATION, AudioManager.VIBRATE_SETTING_OFF);   
  13.     }   
  14.     // 震动  
  15.     protected void vibrate(AudioManager audio){   
  16.         audio.setRingerMode(AudioManager.RINGER_MODE_VIBRATE);   
  17.         audio.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER, AudioManager.VIBRATE_SETTING_ON);   
  18.         audio.setVibrateSetting(AudioManager.VIBRATE_TYPE_NOTIFICATION, AudioManager.VIBRATE_SETTING_ON);   
  19.     }   
  20.     // 静音  
  21.     protected void silent(AudioManager audio){   
  22.         audio.setRingerMode(AudioManager.RINGER_MODE_SILENT);   
  23.         audio.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER, AudioManager.VIBRATE_SETTING_OFF);   
  24.         audio.setVibrateSetting(AudioManager.VIBRATE_TYPE_NOTIFICATION, AudioManager.VIBRATE_SETTING_OFF);   
  25.     }   
  26.     // 改变声音-----减小  
  27.     protected void lowerVoice(AudioManager audio, int voice){   
  28.         audio.setRingerMode(AudioManager.ADJUST_LOWER);   
  29.         audio.adjustVolume(AudioManager.ADJUST_LOWER, voice);   
  30.     }   
  31.     // 改变声音-----增加  
  32.     protected void addVoice(AudioManager audio, int voice){   
  33.         audio.setRingerMode(AudioManager.ADJUST_RAISE);   
  34.         audio.adjustVolume(AudioManager.ADJUST_RAISE, voice);   
  35.     }  
复制代码


这里我使用了BroadcastReceiver(广播接收器)。当需要更改情景模式时,发送一个intent出来,BroadcastReceiver接收到这个intent后根据intent内携带的值判断切换成那种情景模式

BroadcastReceiver的使用需要在androidmanifest文件中申明
Java代码

  1. <receiver android:name=".RingBroadcastReceiver">   
  2.             <intent-filter>   
  3.                 <action android:name="cn.zucc.yoyo.ringmaster.RING_RECEIVER" />   
  4.             </intent-filter>   
  5.         </receiver>  
复制代码

当触发一定情景时只要发送一个Intent。广播接收器就可以接受到,然后执行相应代码
Java代码

  1. Intent intent = new Intent("cn.zucc.yoyo.ringmaster.RING_RECEIVER");   
  2.               Bundle bundle = new Bundle();   
  3.               bundle.putDouble("latitude", currentGeoPoint.getLatitudeE6());   
  4.               bundle.putDouble("longitude", currentGeoPoint.getLongitudeE6());   
  5.               intent.putExtra("location", bundle);   
  6.                 // 发送广播  
  7.               sendBroadcast(intent);  
复制代码


接下来是实时获取用户当前的位置

我们的activity是时常被用户打断的。即被置到后台,用户处理其他事情去了。所以实时更新位置信息就需要使用service组件。该组件将一直运行在后台,除非你停止它。

service的使用也需要在androidmanifest文件中定义
Java代码

  1. <service android:name=".RingService" android:process=":remote">   
  2.             <intent-filter>   
  3.                 <action android:name="cn.zucc.yoyo.ringmaster.RING_SERVICE" />   
  4.             </intent-filter>   
  5.         </service>  
  6.   
复制代码


对于service我们只需要知道它的5个生命周期,然后在相应的周期中干我们需要的事情即可。
而启动一个service,和停止service也很简单

startService(new Intent(                "cn.zucc.yoyo.ringmaster.RING_SERVICE2"));
Java代码

  1. startService(new Intent(   
  2.                 "cn.zucc.yoyo.ringmaster.RING_SERVICE2"));   

  3. stopService(new Intent(   
  4.                 "cn.zucc.yoyo.ringmaster.RING_SERVICE2"));  
复制代码

补充一点,关于手机重力感应,因为也是需要实时判断,所以我也将它添加在service中。
Java代码

  1. private SensorManager sensorMgr ;   
  2.     private SensorEventListener lsn ;   
  3. sensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE);    
  4.            Sensor sensor = sensorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);    
  5.            lsn = new SensorEventListener() {    

  6.                public void onSensorChanged(SensorEvent e) {     
  7.                  //x = e.values[SensorManager.DATA_X];         
  8.                //  y = e.values[SensorManager.DATA_Y];         
  9.                  z = (int) e.values[SensorManager.DATA_Z];       
  10.                  if(z>5&&(audio.getRingerMode()!=AudioManager.RINGER_MODE_NORMAL)){   
  11.                      Intent intent = new Intent("android.provider.Telephony.SMS_RECEIVER");   
  12.                     intent.putExtra("ringmode", 4);   
  13.                     // 发送广播  
  14.                     sendBroadcast(intent);   
  15.                  }else if(z<-5&&(audio.getRingerMode()!=AudioManager.RINGER_MODE_SILENT)){   
  16.                      Intent intent = new Intent("android.provider.Telephony.SMS_RECEIVER");   
  17.                     intent.putExtra("ringmode", 3);   
  18.                     // 发送广播  
  19.                     sendBroadcast(intent);   
  20.                  }   

  21.                 // setTitle("x="+(int)x+","+"y="+(int)y+","+"z="+(int)z);      
  22.               }       

  23.                public void onAccuracyChanged(Sensor s, int accuracy) {       
  24.                }       
  25.            };  
复制代码
   
当手机状态变化时就发送相应的intent广播。。广播接收器接收到后根据intent携带的值,改变情景模式。

而用户当前位置的更新问题也和上面的重力感应更新差不多
Java代码

  1. private LocationManager mLocationManager;   
  2. mLocationManager =  (LocationManager)getSystemService(Context.LOCATION_SERVICE);   
  3.         updateMyLocation(mLocationManager);   

  4. /**更新我的位置 
  5.      *  
  6.      * */  
  7.     String strLocationProvider="test";   
  8.       public void updateMyLocation(LocationManager lm){   

  9.           /* 第一次运行向Location Provider取得Location */  
  10.           Location mLocation01 = getLocationProvider(lm);   

  11.           if(mLocation01!=null)   
  12.           {   
  13.             processLocationUpdated(mLocation01);   
  14.           }   
  15.           else  
  16.           {   
  17.               Toast.makeText(this,"位置初始化出错", Toast.LENGTH_SHORT).show();   
  18.           }   
  19.           /* 创建LocationManager对象,监听Location更改时事件,更新MapView */  
  20.           lm.requestLocationUpdates   
  21.           (strLocationProvider, 2000, 10, mLocationListener01);   
  22.       }   

  23.       public Location getLocationProvider(LocationManager lm)   
  24.       {//设定:地理位置获取的参数信息  
  25.         Location retLocation = null;   
  26.         try  
  27.         {   
  28.           Criteria mCriteria01 = new Criteria();   
  29.           mCriteria01.setAccuracy(Criteria.ACCURACY_FINE);   
  30.           mCriteria01.setAltitudeRequired(false);   
  31.           mCriteria01.setBearingRequired(false);   
  32.           mCriteria01.setCostAllowed(true);   
  33.           mCriteria01.setPowerRequirement(Criteria.POWER_LOW);   
  34.           strLocationProvider = lm.getBestProvider(mCriteria01, true);   
  35.           retLocation = lm.getLastKnownLocation(strLocationProvider);   
  36.         }   
  37.         catch(Exception e)   
  38.         {   
  39.          // mTextView01.setText(e.toString());  
  40.           e.printStackTrace();   
  41.         }   
  42.         return retLocation;   
  43.       }   

  44.       /**位置监听器*/  
  45.       public final LocationListener   
  46.       mLocationListener01 = new LocationListener()   
  47.       {   
  48.           public void onLocationChanged(Location location)   
  49.           {   
  50.               // TODO Auto-generated method stub  
  51.               /* 当手机收到位置更改时,将location传入取得地理坐标 */  
  52.               processLocationUpdated(location);   
  53.           }   

  54.           public void onProviderDisabled(String provider)   
  55.           {   
  56.               // TODO Auto-generated method stub  
  57.               /* 当Provider已离开服务范围时 */  
  58.               Toast.makeText(RingService.this, "无地理位置信息可用", Toast.LENGTH_SHORT).show();   
  59.           }   

  60.           public void onProviderEnabled(String provider)   
  61.           {   
  62.               // TODO Auto-generated method stub  
  63.           }   

  64.           public void onStatusChanged   
  65.           (String provider, int status, Bundle extras)   
  66.           {   
  67.               // TODO Auto-generated method stub  
  68.           }   
  69.       };   

  70.       /* 当手机收到位置更改,将location传入GeoPoint及MapView */  
  71.       private void processLocationUpdated(Location location)   
  72.       {   
  73.           /* 传入Location对象,取得GeoPoint地理坐标 */  
  74.           GeoPoint currentGeoPoint = getGeoByLocation(location);   
  75.           /** 
  76.            * */  
  77.           Log.i("service--------",currentGeoPoint.getLatitudeE6()+":"+currentGeoPoint.getLongitudeE6());   
  78.           //读取记录的位置信息  
  79.               Intent intent = new Intent("android.provider.Telephony.SMS_RECEIVER2");   
  80.               Bundle bundle = new Bundle();   
  81.               bundle.putDouble("latitude", currentGeoPoint.getLatitudeE6());   
  82.               bundle.putDouble("longitude", currentGeoPoint.getLongitudeE6());   
  83.               intent.putExtra("location", bundle);   
  84.                 // 发送广播  
  85.               sendBroadcast(intent);   
  86.               Log.i("service--------", "been send");   


  87.               Intent intent2 = new Intent("cn.yoyo.locationupdate");   
  88.               Bundle bundle2 = new Bundle();   
  89.               bundle2.putDouble("latitude", currentGeoPoint.getLatitudeE6());   
  90.               bundle2.putDouble("longitude", currentGeoPoint.getLongitudeE6());   
  91.               intent2.putExtra("location", bundle2);   
  92.               // 发送广播  
  93.               sendBroadcast(intent2);   
  94.               Log.i("service--------", "been send");   
  95.              // Toast.makeText(this, "情景已切换", Toast.LENGTH_SHORT).show();  

  96.       }   
  97.       /**location->geopoint*/  
  98.       public static GeoPoint getGeoByLocation(Location location)   
  99.       {   
  100.           GeoPoint gp = null;   
  101.           try  
  102.           {   
  103.               /* 当Location存在 */  
  104.               if (location != null)   
  105.               {   
  106.                   double geoLatitude = location.getLatitude()*1E6;   
  107.                   double geoLongitude = location.getLongitude()*1E6;   
  108.                   gp = new GeoPoint((int) geoLatitude, (int) geoLongitude);   
  109.               }   
  110.           }   
  111.           catch(Exception e)   
  112.           {   
  113.               e.printStackTrace();   
  114.           }   
  115.           return gp;   
  116.       }  
  117.   
复制代码

最后就是使用android Google  map .使用关于如何使用Google  map网上也有很详细的介绍,有时间我将专门详细的写一篇关于Google  map的。

这里重点介绍下如何在Mapview上添加自定义标记的问题,当我在查找相关资料时,由于他们用的就是旧版的SDK,所以代码没有运行起来。
要向Mapview添加标记只要如下代码即可。
Java代码

  1. MapLocationOverlay overlay = new MapLocationOverlay(this);   
  2.         mapView.getOverlays().add(overlay);  
  3. 这里我继承Overlay,实现了自己的一个标记MapLocationOverlay   
复制代码

Java代码

  1. public class MapLocationOverlay  extends Overlay {   


  2.     private Bitmap bubbleIcon, shadowIcon;   
  3.     private Bitmap bubbleVolume,bubbleVolumeOff,bubbleVibrate,bubbleVolumeeVibrate;   

  4.     private MapLocationViewer mapLocationViewer;   

  5.     private Paint   innerPaint, borderPaint, textPaint;   


  6.     private RecordLocation selectedMapLocation;   

  7.     private Handler mHandler;   

  8.     public void setinfowindow(Handler handler){   
  9.         this.mHandler = handler;   
  10.     }   
  11.     public MapLocationOverlay(MapLocationViewer     mapLocationViewer) {   

  12.         this.mapLocationViewer = mapLocationViewer;   

  13.         bubbleIcon = BitmapFactory.decodeResource(mapLocationViewer.getResources(),R.drawable.bubble);   
  14.         bubbleVolume = BitmapFactory.decodeResource(mapLocationViewer.getResources(),R.drawable.bubble_volume);   
  15.         bubbleVolumeOff = BitmapFactory.decodeResource(mapLocationViewer.getResources(),R.drawable.bubble_volumeoff);   
  16.         bubbleVibrate = BitmapFactory.decodeResource(mapLocationViewer.getResources(),R.drawable.bubble_vibrate);   
  17.         bubbleVolumeeVibrate = BitmapFactory.decodeResource(mapLocationViewer.getResources(),R.drawable.bubble_volumevibrate);   
  18.         shadowIcon = BitmapFactory.decodeResource(mapLocationViewer.getResources(),R.drawable.shadow);   
  19.     }   

  20.     @Override  
  21.     public boolean onTap(GeoPoint p, MapView    mapView)  {   

  22.         //  Store whether prior popup was displayed so we can call invalidate() & remove it if necessary.  
  23.         boolean isRemovePriorPopup = selectedMapLocation != null;   

  24.         //  Next test whether a new popup should be displayed  
  25.         selectedMapLocation = getHitMapLocation(mapView,p);   
  26.         if ( isRemovePriorPopup || selectedMapLocation != null) {   
  27.             if(selectedMapLocation==null){   
  28.                 //发送消息  
  29.                 Message msg = mHandler.obtainMessage();   
  30.                 msg.what = RingMaster.REFERSH_LOCATION;   
  31.                 Bundle b = new Bundle();   
  32.                 b.putInt("view",android.view.View.GONE);   
  33.                 msg.setData(b);   
  34.                 mHandler.sendMessage(msg);   
  35.             }else{   
  36.                 //发送消息  
  37.                 Message msg = mHandler.obtainMessage();   
  38.                 msg.what = RingMaster.REFERSH_LOCATION;   
  39.                 Bundle b = new Bundle();   
  40.                 b.putString("location", selectedMapLocation.getLocation_Id());   
  41.                 //b.putString("ringmode", selectedMapLocation.getLocation_ring());  
  42.                 b.putDouble("latitude", selectedMapLocation.getLocation_latitude());   
  43.                 b.putDouble("longitude", selectedMapLocation.getLocation_longitude());   
  44.                 b.putInt("view", android.view.View.VISIBLE);   
  45.                 msg.setData(b);   
  46.                 mHandler.sendMessage(msg);   

  47.                 mapView.getController().animateTo(p);   
  48.                 mapView.invalidate();   

  49.             }   
  50.         }   

  51.         //  Lastly return true if we handled this onTap()  
  52.         return selectedMapLocation != null;   
  53.     }   

  54.     @Override  
  55.     public void draw(Canvas canvas, MapView mapView, boolean shadow) {   

  56.         drawMapLocations(canvas, mapView, shadow);   
  57.         //drawInfoWindow(canvas, mapView, shadow);  
  58.     }   

  59.     private RecordLocation getHitMapLocation(MapView    mapView, GeoPoint   tapPoint) {   

  60.         //  Track which MapLocation was hit...if any  
  61.         RecordLocation hitMapLocation = null;   

  62.         RectF hitTestRecr = new RectF();   
  63.         Point screenCoords = new Point();   
  64.         Iterator<RecordLocation> iterator = mapLocationViewer.getMapLocations().iterator();   
  65.         while(iterator.hasNext()) {   
  66.             RecordLocation testLocation = iterator.next();   

  67.             //  Translate the MapLocation's lat/long coordinates to screen coordinates  
  68.             mapView.getProjection().toPixels(testLocation.getPoint(), screenCoords);   

  69.             // Create a 'hit' testing Rectangle w/size and coordinates of our icon  
  70.             // Set the 'hit' testing Rectangle with the size and coordinates of our on screen icon  
  71.             hitTestRecr.set(-bubbleIcon.getWidth()*2,-bubbleIcon.getHeight()*2,bubbleIcon.getWidth()*2,0);   
  72.             hitTestRecr.offset(screenCoords.x,screenCoords.y);   

  73.             //  Finally test for a match between our 'hit' Rectangle and the location clicked by the user  
  74.             mapView.getProjection().toPixels(tapPoint, screenCoords);   
  75.             if (hitTestRecr.contains(screenCoords.x,screenCoords.y)) {   
  76.                 hitMapLocation = testLocation;   
  77.                 break;   
  78.             }   
  79.         }   

  80.         //  Lastly clear the newMouseSelection as it has now been processed  
  81.         tapPoint = null;   

  82.         return hitMapLocation;   
  83.     }   

  84.     private static final int VOLUME=1,VIBRATE=2,VOLUMEOFF=3,VOLUMEVIBRATE=4;   
  85.     private void drawMapLocations(Canvas canvas, MapView    mapView, boolean shadow) {   

  86.         if(mapLocationViewer.getMapLocations()!=null){   

  87.             Iterator<RecordLocation> iterator = mapLocationViewer.getMapLocations().iterator();   
  88.             Point screenCoords = new Point();   
  89.             while(iterator.hasNext()) {   
  90.                 RecordLocation location = iterator.next();   
  91.                 mapView.getProjection().toPixels(location.getPoint(), screenCoords);   

  92.                 if (shadow) {   
  93.                     //  Only offset the shadow in the y-axis as the shadow is angled so the base is at x=0;  
  94.                     canvas.drawBitmap(shadowIcon, screenCoords.x, screenCoords.y - shadowIcon.getHeight(),null);   
  95.                 } else {   
  96.                     switch(Integer.valueOf(location.getLocation_ring())){   
  97.                     case VOLUME:   
  98.                         canvas.drawBitmap(bubbleVolume, screenCoords.x - bubbleVolume.getWidth()/2, screenCoords.y - bubbleVolume.getHeight(),null);   
  99.                         break;   
  100.                     case VIBRATE:   
  101.                         canvas.drawBitmap(bubbleVibrate, screenCoords.x - bubbleVibrate.getWidth()/2, screenCoords.y - bubbleVibrate.getHeight(),null);   
  102.                         break;   
  103.                     case VOLUMEOFF:   
  104.                         canvas.drawBitmap(bubbleVolumeOff, screenCoords.x - bubbleVolumeOff.getWidth()/2, screenCoords.y - bubbleVolumeOff.getHeight(),null);   
  105.                         break;   
  106.                     case VOLUMEVIBRATE:   
  107.                         canvas.drawBitmap(bubbleVolumeeVibrate, screenCoords.x - bubbleVolumeeVibrate.getWidth()/2, screenCoords.y - bubbleVolumeeVibrate.getHeight(),null);   
  108.                         break;   
  109.                     default:   
  110.                         canvas.drawBitmap(bubbleIcon, screenCoords.x - bubbleIcon.getWidth()/2, screenCoords.y - bubbleIcon.getHeight(),null);   
  111.                         break;   
  112.                     }   
  113.                 }   
  114.             }   
  115.         }   
  116.     }   


  117.     public Paint getInnerPaint() {   
  118.         if ( innerPaint == null) {   
  119.             innerPaint = new Paint();   
  120.             innerPaint.setARGB(225, 75, 75, 75); //gray  
  121.             innerPaint.setAntiAlias(true);   
  122.         }   
  123.         return innerPaint;   
  124.     }   

  125.     public Paint getBorderPaint() {   
  126.         if ( borderPaint == null) {   
  127.             borderPaint = new Paint();   
  128.             borderPaint.setARGB(255, 255, 255, 255);   
  129.             borderPaint.setAntiAlias(true);   
  130.             borderPaint.setStyle(Style.STROKE);   
  131.             borderPaint.setStrokeWidth(2);   
  132.         }   
  133.         return borderPaint;   
  134.     }   

  135.     public Paint getTextPaint() {   
  136.         if ( textPaint == null) {   
  137.             textPaint = new Paint();   
  138.             textPaint.setARGB(255, 255, 255, 255);   
  139.             textPaint.setAntiAlias(true);   
  140.         }   
  141.         return textPaint;   
  142.     }  
复制代码

  注:这里可能有些函数是无用的,因为这个类还实现在Mapview上出现infowindow的效果。不过这里为了简化起见我就删了。


最后总结一下:其实开发一个应用,我都是先从view开始,然后更具应用需要的,进行单个功能的开发,最后就是ctrl+c和V了呵呵。
但这里正好是反过来了。想从易道难成列。。。哈哈毕竟是新手,第一次写这种文章,大家见谅吧。

这个应用只有一个activity,既只有一个view。在这个view中有Mapview。
而使用Google  map 基本上就是让这个activity继承MapActivity,然后对这个Mapview对象进行操作了。
这个应用通过两个service分别运行在后台,其一实时更新用户的位置,其二实时跟新手机的重力状态。进而发送相应的intent广播,而这个intent广播携带了情景模式的信息,当boardcastreceiver(广播接收器)接受到这个广播后就调用相应函数并根据intent携带的信息改变手机的情景。而用户每次记录的地点和情景,则使用了XML文件进行读写。
mapview上的自定义标记采用了重写ondraw方法的方式,在底层自己绘制。

这篇关于android map 标示的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/681853

相关文章

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

android-opencv-jni

//------------------start opencv--------------------@Override public void onResume(){ super.onResume(); //通过OpenCV引擎服务加载并初始化OpenCV类库,所谓OpenCV引擎服务即是 //OpenCV_2.4.3.2_Manager_2.4_*.apk程序包,存

从状态管理到性能优化:全面解析 Android Compose

文章目录 引言一、Android Compose基本概念1.1 什么是Android Compose?1.2 Compose的优势1.3 如何在项目中使用Compose 二、Compose中的状态管理2.1 状态管理的重要性2.2 Compose中的状态和数据流2.3 使用State和MutableState处理状态2.4 通过ViewModel进行状态管理 三、Compose中的列表和滚动

Android 10.0 mtk平板camera2横屏预览旋转90度横屏拍照图片旋转90度功能实现

1.前言 在10.0的系统rom定制化开发中,在进行一些平板等默认横屏的设备开发的过程中,需要在进入camera2的 时候,默认预览图像也是需要横屏显示的,在上一篇已经实现了横屏预览功能,然后发现横屏预览后,拍照保存的图片 依然是竖屏的,所以说同样需要将图片也保存为横屏图标了,所以就需要看下mtk的camera2的相关横屏保存图片功能, 如何实现实现横屏保存图片功能 如图所示: 2.mtk

android应用中res目录说明

Android应用的res目录是一个特殊的项目,该项目里存放了Android应用所用的全部资源,包括图片、字符串、颜色、尺寸、样式等,类似于web开发中的public目录,js、css、image、style。。。。 Android按照约定,将不同的资源放在不同的文件夹中,这样可以方便的让AAPT(即Android Asset Packaging Tool , 在SDK的build-tools目

Android fill_parent、match_parent、wrap_content三者的作用及区别

这三个属性都是用来适应视图的水平或者垂直大小,以视图的内容或尺寸为基础的布局,比精确的指定视图的范围更加方便。 1、fill_parent 设置一个视图的布局为fill_parent将强制性的使视图扩展至它父元素的大小 2、match_parent 和fill_parent一样,从字面上的意思match_parent更贴切一些,于是从2.2开始,两个属性都可以使用,但2.3版本以后的建议使

Collection List Set Map的区别和联系

Collection List Set Map的区别和联系 这些都代表了Java中的集合,这里主要从其元素是否有序,是否可重复来进行区别记忆,以便恰当地使用,当然还存在同步方面的差异,见上一篇相关文章。 有序否 允许元素重复否 Collection 否 是 List 是 是 Set AbstractSet 否

Android Environment 获取的路径问题

1. 以获取 /System 路径为例 /*** Return root of the "system" partition holding the core Android OS.* Always present and mounted read-only.*/public static @NonNull File getRootDirectory() {return DIR_ANDR

Android逆向(反调,脱壳,过ssl证书脚本)

文章目录 总结 基础Android基础工具 定位关键代码页面activity定位数据包参数定位堆栈追踪 编写反调脱壳好用的脚本过ssl证书校验抓包反调的脚本打印堆栈bilibili反调的脚本 总结 暑假做了两个月的Android逆向,记录一下自己学到的东西。对于app渗透有了一些思路。 这两个月主要做的是代码分析,对于分析完后的持久化等没有学习。主要是如何反编译源码,如何找到