首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 移动开发 > Android >

android 应用类APP开发小结——android Google 地图 小应用

2012-08-26 
android 应用类APP开发小结——android Google map 小应用首届Google暑期大学生博客分享大赛——2010 Andriod

android 应用类APP开发小结——android Google map 小应用

首届Google暑期大学生博客分享大赛——2010 Andriod篇

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

?

先上截图:

android 应用类APP开发小结——android Google 地图 小应用

?

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

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

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

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

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

?

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

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

麻雀虽小,五脏俱全

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

???? 改变情景模式

???? 实时获取地理位置

???? 实时判断手机重力状态

用到的技术包括:

1.android Google map的应用

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

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

?

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

?

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

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

?

为了记录用户记录的情景地点,我使用了XML作为存储的标准,并将文件存在了SD卡上

XML解析

网络上有很详细的各种解析方式,我采用了其中的一种。如果想了解其他的请Google。。。。。

记录地点信息,我定义了一个POJO类

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

?

?

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

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

?

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

public class MapLocationOverlay  extends Overlay {    private Bitmap bubbleIcon, shadowIcon;    private Bitmap bubbleVolume,bubbleVolumeOff,bubbleVibrate,bubbleVolumeeVibrate;    private MapLocationViewer mapLocationViewer;private PaintinnerPaint, borderPaint, textPaint;      private RecordLocation selectedMapLocation;    private Handler mHandler;    public void setinfowindow(Handler handler){    this.mHandler = handler;    }public MapLocationOverlay(MapLocationViewermapLocationViewer) {this.mapLocationViewer = mapLocationViewer;bubbleIcon = BitmapFactory.decodeResource(mapLocationViewer.getResources(),R.drawable.bubble);bubbleVolume = BitmapFactory.decodeResource(mapLocationViewer.getResources(),R.drawable.bubble_volume);bubbleVolumeOff = BitmapFactory.decodeResource(mapLocationViewer.getResources(),R.drawable.bubble_volumeoff);bubbleVibrate = BitmapFactory.decodeResource(mapLocationViewer.getResources(),R.drawable.bubble_vibrate);bubbleVolumeeVibrate = BitmapFactory.decodeResource(mapLocationViewer.getResources(),R.drawable.bubble_volumevibrate);shadowIcon = BitmapFactory.decodeResource(mapLocationViewer.getResources(),R.drawable.shadow);}@Overridepublic boolean onTap(GeoPoint p, MapViewmapView)  {//  Store whether prior popup was displayed so we can call invalidate() & remove it if necessary.boolean isRemovePriorPopup = selectedMapLocation != null;//  Next test whether a new popup should be displayedselectedMapLocation = getHitMapLocation(mapView,p);if ( isRemovePriorPopup || selectedMapLocation != null) {if(selectedMapLocation==null){//发送消息Message msg = mHandler.obtainMessage();msg.what = RingMaster.REFERSH_LOCATION;Bundle b = new Bundle();b.putInt("view",android.view.View.GONE);msg.setData(b);mHandler.sendMessage(msg);}else{//发送消息Message msg = mHandler.obtainMessage();msg.what = RingMaster.REFERSH_LOCATION;Bundle b = new Bundle();b.putString("location", selectedMapLocation.getLocation_Id());//b.putString("ringmode", selectedMapLocation.getLocation_ring());b.putDouble("latitude", selectedMapLocation.getLocation_latitude());b.putDouble("longitude", selectedMapLocation.getLocation_longitude());b.putInt("view", android.view.View.VISIBLE);msg.setData(b);mHandler.sendMessage(msg);mapView.getController().animateTo(p);mapView.invalidate();}}//  Lastly return true if we handled this onTap()return selectedMapLocation != null;}    @Overridepublic void draw(Canvas canvas, MapViewmapView, boolean shadow) {   drawMapLocations(canvas, mapView, shadow);   //drawInfoWindow(canvas, mapView, shadow);    }    private RecordLocation getHitMapLocation(MapViewmapView, GeoPointtapPoint) {    //  Track which MapLocation was hit...if any    RecordLocation hitMapLocation = null;    RectF hitTestRecr = new RectF();Point screenCoords = new Point();    Iterator<RecordLocation> iterator = mapLocationViewer.getMapLocations().iterator();    while(iterator.hasNext()) {    RecordLocation testLocation = iterator.next();    //  Translate the MapLocation's lat/long coordinates to screen coordinates    mapView.getProjection().toPixels(testLocation.getPoint(), screenCoords);    // Create a 'hit' testing Rectangle w/size and coordinates of our icon    // Set the 'hit' testing Rectangle with the size and coordinates of our on screen icon    hitTestRecr.set(-bubbleIcon.getWidth()*2,-bubbleIcon.getHeight()*2,bubbleIcon.getWidth()*2,0);    hitTestRecr.offset(screenCoords.x,screenCoords.y);    //  Finally test for a match between our 'hit' Rectangle and the location clicked by the user    mapView.getProjection().toPixels(tapPoint, screenCoords);    if (hitTestRecr.contains(screenCoords.x,screenCoords.y)) {    hitMapLocation = testLocation;    break;    }    }    //  Lastly clear the newMouseSelection as it has now been processed    tapPoint = null;    return hitMapLocation;    }    private static final int VOLUME=1,VIBRATE=2,VOLUMEOFF=3,VOLUMEVIBRATE=4;    private void drawMapLocations(Canvas canvas, MapViewmapView, boolean shadow) {    if(mapLocationViewer.getMapLocations()!=null){        Iterator<RecordLocation> iterator = mapLocationViewer.getMapLocations().iterator();    Point screenCoords = new Point();    while(iterator.hasNext()) {    RecordLocation location = iterator.next();    mapView.getProjection().toPixels(location.getPoint(), screenCoords);        if (shadow) {    //  Only offset the shadow in the y-axis as the shadow is angled so the base is at x=0;    canvas.drawBitmap(shadowIcon, screenCoords.x, screenCoords.y - shadowIcon.getHeight(),null);    } else {    switch(Integer.valueOf(location.getLocation_ring())){    case VOLUME:    canvas.drawBitmap(bubbleVolume, screenCoords.x - bubbleVolume.getWidth()/2, screenCoords.y - bubbleVolume.getHeight(),null);    break;    case VIBRATE:    canvas.drawBitmap(bubbleVibrate, screenCoords.x - bubbleVibrate.getWidth()/2, screenCoords.y - bubbleVibrate.getHeight(),null);    break;    case VOLUMEOFF:    canvas.drawBitmap(bubbleVolumeOff, screenCoords.x - bubbleVolumeOff.getWidth()/2, screenCoords.y - bubbleVolumeOff.getHeight(),null);    break;    case VOLUMEVIBRATE:    canvas.drawBitmap(bubbleVolumeeVibrate, screenCoords.x - bubbleVolumeeVibrate.getWidth()/2, screenCoords.y - bubbleVolumeeVibrate.getHeight(),null);    break;    default:    canvas.drawBitmap(bubbleIcon, screenCoords.x - bubbleIcon.getWidth()/2, screenCoords.y - bubbleIcon.getHeight(),null);    break;    }    }    }    }    }  public Paint getInnerPaint() {if ( innerPaint == null) {innerPaint = new Paint();innerPaint.setARGB(225, 75, 75, 75); //grayinnerPaint.setAntiAlias(true);}return innerPaint;}public Paint getBorderPaint() {if ( borderPaint == null) {borderPaint = new Paint();borderPaint.setARGB(255, 255, 255, 255);borderPaint.setAntiAlias(true);borderPaint.setStyle(Style.STROKE);borderPaint.setStrokeWidth(2);}return borderPaint;}public Paint getTextPaint() {if ( textPaint == null) {textPaint = new Paint();textPaint.setARGB(255, 255, 255, 255);textPaint.setAntiAlias(true);}return textPaint;}

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

?

?

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

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

?

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

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

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

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

?

1 楼 android_mini 2010-07-31   哈哈 ,不错,我也刚写了一篇博文,你去看看哈 2 楼 nonoh2006 2010-08-02   你好,我的一个程序之中也需要使用的传感器和GPS相关信息的实施传递,从你的代码中,我没能了解到在activity 中怎么样接受 service 中的数据, 请问下 能不能发一下该工程的源代码
  或者能不能给我相信说下  service的数据接收   谢谢  我的邮箱zswenchao2002@163.com 3 楼 ec256 2010-10-22   你好,我有个问题想请教,Sensor  在service中可以正常监听吗,是不是还需要什么权限啊,能否把你的源代码给我 啊 ec256@163.com  谢谢 4 楼 yjdzh 2010-12-09   可以共享一下代码嘛 5 楼 左手风袖 2011-04-04   能否共享一下代码?

热点排行