Android系列只androidGooglemap小应用

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

先上截图:

Android系列只androidGooglemap小应用

应用的主要功能是根据适当的情景(如地点,手机状态等)为用户自动的切换情景模式。

比方说:手机向上是铃音+震动,当开会时,将手机翻转,将自动切换成静音模式。

还可以根据经纬度,到达一个地方后自动切换成用户预先设置的情景模式。

(当然,由于没找到合适的经纬度换算工具,经纬度的判断目前只能是精确位置,不是范围值。

因此只能算是个学习的小应用了,实际的应用还有待完善啊。如果有高手知道的话,麻烦告诉我下。万分感谢)

-------------------------废话不多说开始代码部分-----------------------------------------------------

虽然是一个只有一个页面的小应用,但是

麻雀虽小,五脏俱全

这个应用的功能点主要有:

     改变情景模式

     实时获取地理位置

     实时判断手机重力状态

用到的技术包括:

1.android Google map的应用

2.Android组件的使用
    Activity(MapActivity)
    Service
    Broadcastreceiver

3.Xml解析
4.文件存储
5.传感器使用
6.底层绘图
7.自定义view

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

首先是权限问题,很多新手都犯了这个毛病,程序出错,往往是权限没有添加。

 

  
    
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类

 

  
    
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的解析器,和网络上的其他文章一样就不多说了。能拿来用就成。

 

 

  
    
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
34 try {
35 InputStream inputStream = new ByteArrayInputStream(xml.getBytes());
36 Xml.parse(inputStream, Xml.Encoding.UTF_8,
37 root.getContentHandler());
38 } catch (Exception e) {
39 throw new RuntimeException(e);
40 }
41 return messages;
42 }

POJO类转化成XML字符串

 

 

  
    
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
10 for ( int i = 0 ;i < data.size();i ++ ){
11 serializer.startTag( "" , " Location " );
12
13 serializer.startTag( "" , " id " );
14 serializer.text(data.get(i).getLocation_Id());
15 serializer.endTag( "" , " id " );
16
17 serializer.startTag( "" , " ring " );
18 serializer.text(data.get(i).getLocation_ring());
19 serializer.endTag( "" , " ring " );
20
21 serializer.startTag( "" , " latitude " );
22 serializer.text(String.valueOf(data.get(i).getLocation_latitude()));
23 serializer.endTag( "" , " latitude " );
24
25 serializer.startTag( "" , " longitude " );
26 serializer.text(String.valueOf(data.get(i).getLocation_longitude()));
27 serializer.endTag( "" , " longitude " );
28
29 serializer.endTag( "" , " Location " );
30
31 }
32
33
34 serializer.endTag( "" , " Locations " );
35 serializer.endDocument();
36 return writer.toString();
37 }
38 catch (Exception e)
39 {
40 throw new RuntimeException(e);
41 }
42 }

 

有了XML的字符串后只要将它存储起来就行,需要使用是再读取

以下是存储和读取文件函数。由于SD卡的读取还需要判断SD卡的状态,函数比较长,就贴存手机内存的代码

反正大同小异

 

  
    
1 public static InputStream readInternalFileInputStream(Context context,String fileName){
2 /**
3 * 读取手机内存文件
4 * */
5
6 try {
7 FileInputStream fis = context.openFileInput(fileName);
8
9 return fis;
10 } catch (Exception e){
11 return null ;
12 }
13
14 }
15 public static String readInternalFile(Context context,String fileName){
16 /**
17 * 读取手机内存文件
18 * */
19
20 try {
21 byte [] buffer = new byte [ 512 ];
22 int read = 0 ;
23 StringBuffer stringbuffer = new StringBuffer();
24 FileInputStream fis = context.openFileInput(fileName);
25 do {
26 read = fis.read(buffer);
27 if (read > 0 )
28 stringbuffer.append( new String(buffer, 0 , read, " utf-8 " ));
29
30 } while (read !=- 1 );
31 fis.close();
32 return stringbuffer.toString();
33 } catch (Exception e){
34 return null ;
35 }
36
37 }

 

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

手机的铃音设置

 

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

 

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

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

 

  
    
1 < receiver android:name = " .RingBroadcastReceiver " >
2 < intent - filter >
3 < action android:name = " cn.Test.xiaoqin.ringmaster.RING_RECEIVER " />
4 </ intent - filter >
5 </ receiver >

 

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

 

  
    
1 Intent intent = new Intent( " cn.Test.xiaoqin.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文件中定义

 

  
    
1 < service android:name = " .RingService " android:process = " :remote " >
2 < intent - filter >
3 < action android:name = " cn.Test.xiaoqin.ringmaster.RING_SERVICE " />
4 </ intent - filter >
5 </ service >

 

对于service我们只需要知道它的5个生命周期,然后在相应的周期中干我们需要的事情即可。

而启动一个service,和停止service也很简单

startService(new Intent(
                "cn.Test.xiaoqin.ringmaster.RING_SERVICE2"));

 

  
    
1 startService( new Intent(
2 " cn.Test.xiaoqin.ringmaster.RING_SERVICE2 " ));
3
4 stopService( new Intent(
5 " cn.Test.xiaoqin.ringmaster.RING_SERVICE2 " ));

 

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

 

 

  
    
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
7 public void onSensorChanged(SensorEvent e) {
8 // x = e.values[SensorManager.DATA_X];
9 // y = e.values[SensorManager.DATA_Y];
10   z = ( int ) e.values[SensorManager.DATA_Z];
11 if (z > 5 && (audio.getRingerMode() != AudioManager.RINGER_MODE_NORMAL)){
12 Intent intent = new Intent( " android.provider.Telephony.SMS_RECEIVER " );
13 intent.putExtra( " ringmode " , 4 );
14 // 发送广播
15   sendBroadcast(intent);
16 } else if (z <- 5 && (audio.getRingerMode() != AudioManager.RINGER_MODE_SILENT)){
17 Intent intent = new Intent( " android.provider.Telephony.SMS_RECEIVER " );
18 intent.putExtra( " ringmode " , 3 );
19 // 发送广播
20   sendBroadcast(intent);
21 }
22
23 // setTitle("x="+(int)x+","+"y="+(int)y+","+"z="+(int)z);
24   }
25
26 public void onAccuracyChanged(Sensor s, int accuracy) {
27 }
28 };

 

 当手机状态变化时就发送相应的intent广播。。广播接收器接收到后根据intent携带的值,改变情景模式。

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

 

  
    
1 private LocationManager mLocationManager;
2 mLocationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
3 updateMyLocation(mLocationManager);
4
5 /** 更新我的位置
6 *
7 * */
8 String strLocationProvider = " test " ;
9 public void updateMyLocation(LocationManager lm){
10
11 /* 第一次运行向Location Provider取得Location */
12 Location mLocation01 = getLocationProvider(lm);
13
14 if (mLocation01 != null )
15 {
16 processLocationUpdated(mLocation01);
17 }
18 else
19 {
20 Toast.makeText( this , " 位置初始化出错 " , Toast.LENGTH_SHORT).show();
21 }
22 /* 创建LocationManager对象,监听Location更改时事件,更新MapView */
23 lm.requestLocationUpdates
24 (strLocationProvider, 2000 , 10 , mLocationListener01);
25 }
26
27 public Location getLocationProvider(LocationManager lm)
28 { // 设定:地理位置获取的参数信息
29 Location retLocation = null ;
30 try
31 {
32 Criteria mCriteria01 = new Criteria();
33 mCriteria01.setAccuracy(Criteria.ACCURACY_FINE);
34 mCriteria01.setAltitudeRequired( false );
35 mCriteria01.setBearingRequired( false );
36 mCriteria01.setCostAllowed( true );
37 mCriteria01.setPowerRequirement(Criteria.POWER_LOW);
38 strLocationProvider = lm.getBestProvider(mCriteria01, true );
39 retLocation = lm.getLastKnownLocation(strLocationProvider);
40 }
41 catch (Exception e)
42 {
43 // mTextView01.setText(e.toString());
44 e.printStackTrace();
45 }
46 return retLocation;
47 }
48
49 /** 位置监听器 */
50 public final LocationListener
51 mLocationListener01 = new LocationListener()
52 {
53 public void onLocationChanged(Location location)
54 {
55 // TODO Auto-generated method stub
56 /* 当手机收到位置更改时,将location传入取得地理坐标 */
57 processLocationUpdated(location);
58 }
59
60 public void onProviderDisabled(String provider)
61 {
62 // TODO Auto-generated method stub
63 /* 当Provider已离开服务范围时 */
64 Toast.makeText(RingService. this , " 无地理位置信息可用 " , Toast.LENGTH_SHORT).show();
65 }
66
67 public void onProviderEnabled(String provider)
68 {
69 // TODO Auto-generated method stub
70 }
71
72 public void onStatusChanged
73 (String provider, int status, Bundle extras)
74 {
75 // TODO Auto-generated method stub
76 }
77 };
78
79 /* 当手机收到位置更改,将location传入GeoPoint及MapView */
80 private void processLocationUpdated(Location location)
81 {
82 /* 传入Location对象,取得GeoPoint地理坐标 */
83 GeoPoint currentGeoPoint = getGeoByLocation(location);
84 /**
85 * */
86 Log.i( " service-------- " ,currentGeoPoint.getLatitudeE6() + " : " + currentGeoPoint.getLongitudeE6());
87 // 读取记录的位置信息
88 Intent intent = new Intent( " android.provider.Telephony.SMS_RECEIVER2 " );
89 Bundle bundle = new Bundle();
90 bundle.putDouble( " latitude " , currentGeoPoint.getLatitudeE6());
91 bundle.putDouble( " longitude " , currentGeoPoint.getLongitudeE6());
92 intent.putExtra( " location " , bundle);
93 // 发送广播
94 sendBroadcast(intent);
95 Log.i( " service-------- " , " been send " );
96
97
98 Intent intent2 = new Intent( " cn.yoyo.locationupdate " );
99 Bundle bundle2 = new Bundle();
100 bundle2.putDouble( " latitude " , currentGeoPoint.getLatitudeE6());
101 bundle2.putDouble( " longitude " , currentGeoPoint.getLongitudeE6());
102 intent2.putExtra( " location " , bundle2);
103 // 发送广播
104 sendBroadcast(intent2);
105 Log.i( " service-------- " , " been send " );
106 // Toast.makeText(this, "情景已切换", Toast.LENGTH_SHORT).show();
107
108 }
109 /** location->geopoint */
110 public static GeoPoint getGeoByLocation(Location location)
111 {
112 GeoPoint gp = null ;
113 try
114 {
115 /* 当Location存在 */
116 if (location != null )
117 {
118 double geoLatitude = location.getLatitude() * 1E6;
119 double geoLongitude = location.getLongitude() * 1E6;
120 gp = new GeoPoint(( int ) geoLatitude, ( int ) geoLongitude);
121 }
122 }
123 catch (Exception e)
124 {
125 e.printStackTrace();
126 }
127 return gp;
128 }

 

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

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

要向Mapview添加标记只要如下代码即可。

 

  
    
1 MapLocationOverlay overlay = new MapLocationOverlay( this );
2 mapView.getOverlays().add(overlay);

 

在这里继承Overlay,实现了一个标记MapLocationOverlay

 

 

  
    
1 public class MapLocationOverlay extends Overlay {
2
3
4 private Bitmap bubbleIcon, shadowIcon;
5 private Bitmap bubbleVolume,bubbleVolumeOff,bubbleVibrate,bubbleVolumeeVibrate;
6
7 private MapLocationViewer mapLocationViewer;
8
9 private Paint innerPaint, borderPaint, textPaint;
10
11
12 private RecordLocation selectedMapLocation;
13
14 private Handler mHandler;
15
16 public void setinfowindow(Handler handler){
17 this .mHandler = handler;
18 }
19 public MapLocationOverlay(MapLocationViewer mapLocationViewer) {
20
21 this .mapLocationViewer = mapLocationViewer;
22
23 bubbleIcon = BitmapFactory.decodeResource(mapLocationViewer.getResources(),R.drawable.bubble);
24 bubbleVolume = BitmapFactory.decodeResource(mapLocationViewer.getResources(),R.drawable.bubble_volume);
25 bubbleVolumeOff = BitmapFactory.decodeResource(mapLocationViewer.getResources(),R.drawable.bubble_volumeoff);
26 bubbleVibrate = BitmapFactory.decodeResource(mapLocationViewer.getResources(),R.drawable.bubble_vibrate);
27 bubbleVolumeeVibrate = BitmapFactory.decodeResource(mapLocationViewer.getResources(),R.drawable.bubble_volumevibrate);
28 shadowIcon = BitmapFactory.decodeResource(mapLocationViewer.getResources(),R.drawable.shadow);
29 }
30
31 @Override
32 public boolean onTap(GeoPoint p, MapView mapView) {
33
34 // Store whether prior popup was displayed so we can call invalidate() & remove it if necessary.
35 boolean isRemovePriorPopup = selectedMapLocation != null ;
36
37 // Next test whether a new popup should be displayed
38 selectedMapLocation = getHitMapLocation(mapView,p);
39 if ( isRemovePriorPopup || selectedMapLocation != null ) {
40 if (selectedMapLocation == null ){
41 // 发送消息
42 Message msg = mHandler.obtainMessage();
43 msg.what = RingMaster.REFERSH_LOCATION;
44 Bundle b = new Bundle();
45 b.putInt( " view " ,android.view.View.GONE);
46 msg.setData(b);
47 mHandler.sendMessage(msg);
48 } else {
49 // 发送消息
50 Message msg = mHandler.obtainMessage();
51 msg.what = RingMaster.REFERSH_LOCATION;
52 Bundle b = new Bundle();
53 b.putString( " location " , selectedMapLocation.getLocation_Id());
54 // b.putString("ringmode", selectedMapLocation.getLocation_ring());
55 b.putDouble( " latitude " , selectedMapLocation.getLocation_latitude());
56 b.putDouble( " longitude " , selectedMapLocation.getLocation_longitude());
57 b.putInt( " view " , android.view.View.VISIBLE);
58 msg.setData(b);
59 mHandler.sendMessage(msg);
60
61 mapView.getController().animateTo(p);
62 mapView.invalidate();
63
64 }
65 }
66
67 // Lastly return true if we handled this onTap()
68 return selectedMapLocation != null ;
69 }
70
71 @Override
72 public void draw(Canvas canvas, MapView mapView, boolean shadow) {
73
74 drawMapLocations(canvas, mapView, shadow);
75 // drawInfoWindow(canvas, mapView, shadow);
76 }
77
78 private RecordLocation getHitMapLocation(MapView mapView, GeoPoint tapPoint) {
79
80 // Track which MapLocation was hit...if any
81 RecordLocation hitMapLocation = null ;
82
83 RectF hitTestRecr = new RectF();
84 Point screenCoords = new Point();
85 Iterator < RecordLocation > iterator = mapLocationViewer.getMapLocations().iterator();
86 while (iterator.hasNext()) {
87 RecordLocation testLocation = iterator.next();
88
89 // Translate the MapLocation's lat/long coordinates to screen coordinates
90 mapView.getProjection().toPixels(testLocation.getPoint(), screenCoords);
91
92 // Create a 'hit' testing Rectangle w/size and coordinates of our icon
93 // Set the 'hit' testing Rectangle with the size and coordinates of our on screen icon
94 hitTestRecr.set( - bubbleIcon.getWidth() * 2 , - bubbleIcon.getHeight() * 2 ,bubbleIcon.getWidth() * 2 , 0 );
95 hitTestRecr.offset(screenCoords.x,screenCoords.y);
96
97 // Finally test for a match between our 'hit' Rectangle and the location clicked by the user
98 mapView.getProjection().toPixels(tapPoint, screenCoords);
99 if (hitTestRecr.contains(screenCoords.x,screenCoords.y)) {
100 hitMapLocation = testLocation;
101 break ;
102 }
103 }
104
105 // Lastly clear the newMouseSelection as it has now been processed
106 tapPoint = null ;
107
108 return hitMapLocation;
109 }
110
111 private static final int VOLUME = 1 ,VIBRATE = 2 ,VOLUMEOFF = 3 ,VOLUMEVIBRATE = 4 ;
112 private void drawMapLocations(Canvas canvas, MapView mapView, boolean shadow) {
113
114 if (mapLocationViewer.getMapLocations() != null ){
115
116 Iterator < RecordLocation > iterator = mapLocationViewer.getMapLocations().iterator();
117 Point screenCoords = new Point();
118 while (iterator.hasNext()) {
119 RecordLocation location = iterator.next();
120 mapView.getProjection().toPixels(location.getPoint(), screenCoords);
121
122 if (shadow) {
123 // Only offset the shadow in the y-axis as the shadow is angled so the base is at x=0;
124 canvas.drawBitmap(shadowIcon, screenCoords.x, screenCoords.y - shadowIcon.getHeight(), null );
125 } else {
126 switch (Integer.valueOf(location.getLocation_ring())){
127 case VOLUME:
128 canvas.drawBitmap(bubbleVolume, screenCoords.x - bubbleVolume.getWidth() / 2 , screenCoords.y - bubbleVolume.getHeight(), null );
129 break ;
130 case VIBRATE:
131 canvas.drawBitmap(bubbleVibrate, screenCoords.x - bubbleVibrate.getWidth() / 2 , screenCoords.y - bubbleVibrate.getHeight(), null );
132 break ;
133 case VOLUMEOFF:
134 canvas.drawBitmap(bubbleVolumeOff, screenCoords.x - bubbleVolumeOff.getWidth() / 2 , screenCoords.y - bubbleVolumeOff.getHeight(), null );
135 break ;
136 case VOLUMEVIBRATE:
137 canvas.drawBitmap(bubbleVolumeeVibrate, screenCoords.x - bubbleVolumeeVibrate.getWidth() / 2 , screenCoords.y - bubbleVolumeeVibrate.getHeight(), null );
138 break ;
139 default :
140 canvas.drawBitmap(bubbleIcon, screenCoords.x - bubbleIcon.getWidth() / 2 , screenCoords.y - bubbleIcon.getHeight(), null );
141 break ;
142 }
143 }
144 }
145 }
146 }
147
148
149 public Paint getInnerPaint() {
150 if ( innerPaint == null ) {
151 innerPaint = new Paint();
152 innerPaint.setARGB( 225 , 75 , 75 , 75 ); // gray
153 innerPaint.setAntiAlias( true );
154 }
155 return innerPaint;
156 }
157
158 public Paint getBorderPaint() {
159 if ( borderPaint == null ) {
160 borderPaint = new Paint();
161 borderPaint.setARGB( 255 , 255 , 255 , 255 );
162 borderPaint.setAntiAlias( true );
163 borderPaint.setStyle(Style.STROKE);
164 borderPaint.setStrokeWidth( 2 );
165 }
166 return borderPaint;
167 }
168
169 public Paint getTextPaint() {
170 if ( textPaint == null ) {
171 textPaint = new Paint();
172 textPaint.setARGB( 255 , 255 , 255 , 255 );
173 textPaint.setAntiAlias( true );
174 }
175 return textPaint;
176 }

 

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

最后总结一下:其实开发一个应用,我都是先从view开始,然后更具应用需要的,进行单个功能的开发,最后就是ctrl+c和V了呵呵。

但这里正好是反过来了。想从易道难成列。。。哈哈毕竟是新手,第一次写这种文章,大家见谅吧。

这个应用只有一个activity,既只有一个view。在这个view中有Mapview。

而使用Google map 基本上就是让这个activity继承MapActivity,然后对这个Mapview对象进行操作了。

这个应用通过两个service分别运行在后台,其一实时更新用户的位置,其二实时跟新手机的重力状态。进而发送相应的intent广播,而这个intent广播携带了情景模式的信息,当boardcastreceiver(广播接收器)接受到这个广播后就调用相应函数并根据intent携带的信息改变手机的情景。而用户每次记录的地点和情景,则使用了XML文件进行读写。

在mapview上的自定义标记采用了重写ondraw方法的方式,在底层自己绘制。

 

 

 

 

 

 

你可能感兴趣的:(googlemap)