终于讲到GPS了!现在的LBS如火如荼的发展,Foursquare更是日进千里!有很多圈里人说,创业团队如果想在Android方面创业,最好是开发基于地理位置的应用。可以把电子商务、SNS、Android智能设备完美的融合在一起。今天我们的主角就是GPS。

在Android开发过程中,一直有人在问,怎么在地图上绘制文本或加载图片。今天我们就来实现这个功能,先基础后深入。慢慢的积累才能在GPS这块稳步的了解更多。废话不多说,直接上图,有图有真相嘛。呵呵,截图如下:

(图1) (图2)

图1:是运行程序后出现的界面;

图2:是单价天涯海角后出现的界面;

根据上面截图,我们来完成整个Demo的开发过程。

1、当然,首先我们的申请Google Map服务,至于怎么申请,网上有很多的参考资料或查看开发文档,这里我就不说废话。

2、下载Google API,可能有些童靴在安装Android SDK时,没有把GoogleAPI顺带安装了。由于开发Google Map应用需要基于google aip,所以这里我们就要安装这个。至于怎么安装,我这里提供两种方法:(1)、Window ->Android SDK android AVD Manager->Available Package--->出现Google APIs by Google Inc下载;(2)、直接在网上下载google_apis-8文件,之后将此文件存放在add-ons文件中,之后重启eclipse工具,再按照上面的就出现你想要的了。

3、好了,预前准备都做好之后,该真枪实战了。呵呵,首先新建一个项目,命名为ScenicDisplay。

4、编写布局文件,代码如下:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    android:orientation="vertical"     android:padding="0px"    android:layout_margin="0px">    <TextView        android:id="@+id/textview"        android:layout_width="fill_parent"        android:layout_height="50px"        android:background="#F0FFFF"        android:textColor="#0000CD"        android:padding="8dp"        android:text=""        />    <com.google.android.maps.MapView        android:id="@+id/map"        android:layout_width="fill_parent"        android:layout_height="fill_parent"        android:apiKey="这里的apiKey写上你自己申请的"        android:clickable="true"/>    <LinearLayout         android:id="@+id/zoom"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_gravity="bottom"        android:gravity="center_horizontal" /></LinearLayout>

5、在drawable-mdpi文件夹中存放一张图片,也就是上图中显示的五角星,图片可以自己添加设置一张。

6、编写主程序Activity代码,如下:

package com.wyf.wpf;import java.util.ArrayList;import java.util.List;import android.app.AlertDialog;import android.content.DialogInterface;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Point;import android.graphics.RectF;import android.graphics.drawable.Drawable;import android.os.Bundle;import android.view.Menu;import android.view.MenuItem;import android.widget.TextView;import android.widget.Toast;import com.google.android.maps.GeoPoint;import com.google.android.maps.ItemizedOverlay;import com.google.android.maps.MapActivity;import com.google.android.maps.MapController;import com.google.android.maps.MapView;import com.google.android.maps.MyLocationOverlay;import com.google.android.maps.Overlay;import com.google.android.maps.OverlayItem;import com.google.android.maps.Projection;public class ScenicDisplayActivity extends MapActivity {// 声明变量private TextView textView;private MapView mapView;/* * 控制地图移动、伸缩,以某个GPS坐标为中心,控制MapView中的View组件,管理Overlay提供View的基本功能。 */private MapController mapController;/* * Overlay:此类是一种专门在Target中的选择图上用2D图像进行标记的类,可用于覆盖在地 * 图(MapView)表面的图层,可以把它当成一个画板(Canvas),在重叠的Overlay对象上 * 绘制线条、地标。它有两个子类为ItemizedOverlay类、MyLocationOverlay类 */// 声明图层private positionOverlay pOverlay;private MyLocationOverlay myLocationOverlay;// 声明菜单private static final int MENU_CC = Menu.FIRST;private static final int MENU_SUN = Menu.FIRST + 1;private static final int MENU_TYHJ = Menu.FIRST + 2;// 声明数组,用于存放经纬度private GeoPoint[] position;/** Called when the activity is first created. */@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);textView = (TextView) findViewById(R.id.textview);mapView = (MapView) findViewById(R.id.map);// 通过MapView来取得MapController对象mapController = mapView.getController();//运用MapController类的setZoom方法控制地图缩放的尺度,数值越大,地图的细节就越详细mapController.setZoom(17);// 设置地图模式mapView.setTraffic(true);/* * Map的zoom采用了built-in机制,可以通过setBuiltInZoomControls(boolean) * 来设置是否在地图上显示zoom控件 */mapView.setBuiltInZoomControls(true);// 获取经纬度值getPosition();getView(mapView);}// 设置经纬度public void getPosition() {position = new GeoPoint[3];position[0] = new GeoPoint((int) (40.362642 * 1000000),(int) (116.019793 * 1000000));position[1] = new GeoPoint((int) (45.789361 * 1000000),(int) (126.600048 * 1000000));position[2] = new GeoPoint((int) (18.292023 * 1000000),(int) (109.347711 * 1000000));}// 创建菜单选项@Overridepublic boolean onCreateOptionsMenu(Menu menu) {// TODO Auto-generated method stubmenu.add(0, MENU_CC, 0, "长城八达岭");menu.add(0, MENU_SUN, 1, "太阳岛");menu.add(0, MENU_TYHJ, 2, "天涯海角");return super.onCreateOptionsMenu(menu);}// 监听菜单选项事件@Overridepublic boolean onOptionsItemSelected(MenuItem item) {// TODO Auto-generated method stubswitch (item.getItemId()) {case MENU_CC:mapController.animateTo(position[0]);showDialog("世界文化遗产、国家5A级景区、国家重点文物保护单位、"+ "国家重点风景名胜区、中国旅游胜地四十佳之首、全国文明旅游风景示范区。");break;case MENU_SUN:mapController.animateTo(position[1]);textView.setText("是国内最大的城市中心江曼滩湿地景观,周边栽植北方特有的菩提树之称的康段。");break;case MENU_TYHJ:mapController.animateTo(position[2]);textView.setText("有热带海滩花岗岩风景区、购物区和度假村组成集成热带海洋风光....");break;}return super.onOptionsItemSelected(item);}/* * 用于判断服务器是否显示远程信息,如驾车导航,是MapActivity类中必须实现的子类; 返回true则显示远程信息,否则不显示 */@Overrideprotected boolean isRouteDisplayed() {// TODO Auto-generated method stubreturn false;}/* * //该方法是将我们定义好的图层覆盖在MapView上1、得到MapView中的图层,增加的图标以及图标的位置 * 2、得到我们自定义的图层(myLocationOverlay、positionOverlay)并处理定位功能调用的动作 * 3、将我们得到的图层放到MapView地图中 */public void getView(MapView map) {// 得到MapView中的图层List<Overlay> overlays = mapView.getOverlays();// 增加图标Drawable drawable = getResources().getDrawable(R.drawable.star_big_on);// 设置图标的位置drawable.setBounds(-drawable.getMinimumWidth(),-drawable.getMinimumHeight(), 0, 0);/* * myLocationOverlay对象调用其runOnFirstFix() * 方法并传入runnable参数,在其run方法中,去定义每次更新时执行程序块中的动作 * 将MapView设置成一般地图试图模式、修改地图缩放成度和目标地点移动等动作 */myLocationOverlay = new MyLocationOverlay(this, mapView);myLocationOverlay.runOnFirstFix(new Runnable() {@Overridepublic void run() {// TODO Auto-generated method stubmapView.setTraffic(true);mapController.setZoom(17);mapController.animateTo(myLocationOverlay.getMyLocation());}});overlays.add(myLocationOverlay);pOverlay = new positionOverlay(drawable);overlays.add(pOverlay);}@Overrideprotected void onResume() {// TODO Auto-generated method stubsuper.onResume();myLocationOverlay.enableMyLocation();}@Overrideprotected void onStop() {// TODO Auto-generated method stubsuper.onStop();myLocationOverlay.disableMyLocation();}// 对话框显示public void showDialog(String str) {new AlertDialog.Builder(ScenicDisplayActivity.this).setTitle("景点简介").setMessage(str).setNegativeButton("确定", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {// TODO Auto-generated method stubdialog.dismiss();}}).show();}/* * ItemizedOverlay:此类可以让我们在地图上添加多条信息,不同的信息可以添加到不同的 * 图层上,图层与图层之间可以重叠,就想我们在绘制游戏背景一样,最里面那层是背景层,接着可以绘制多个元素在外层,然后将外层重叠在背景层上。 */private class positionOverlay extends ItemizedOverlay<OverlayItem> {private final int mRadius = 5;// 定义一个列表、用于装我们所要规定的旅游风景区private List<OverlayItem> items = new ArrayList<OverlayItem>();// 在地图上添加图标public positionOverlay(Drawable drawable) {super(drawable);// TODO Auto-generated constructor stubitems.add(new OverlayItem(position[0], "中国长城八达岭", "21度"));items.add(new OverlayItem(position[1], "中国首批A5", "16度"));items.add(new OverlayItem(position[2], "中国名旅", "32度"));populate();// 处理positionOverlay类之后所需要的动作}// 根据编号抓取对应的"OverlayItem"对象返回,创建出图标的实体@Overrideprotected OverlayItem createItem(int i) {// TODO Auto-generated method stubreturn items.get(i);}// "size"返回这个图层告知总共包含了多少个图标@Overridepublic int size() {// TODO Auto-generated method stubreturn items.size();}/* * 该方法用于处理用户所单击的图标的业务处理,如果不实现其方法,用户单击到图标时就不会有任何特殊的反应 */@Overrideprotected boolean onTap(int index) {// TODO Auto-generated method stubToast.makeText(ScenicDisplayActivity.this,"今天的气温是" + items.get(index).getSnippet(),Toast.LENGTH_SHORT).show();return super.onTap(index);}/* * 1、canvas:用来绘制的画布2、mapView:需要被标记的MapView * 3、shadow:为true则需要绘制阴影图层,否则需要绘制内容图层 */@Overridepublic boolean draw(Canvas canvas, MapView mapView, boolean shadow,long when) {// TODO Auto-generated method stub/* * Projection类代表了MapView上得视窗坐标与经纬度坐标的映射关系,用MapView * 对象调用getProjection()就可以得到该地图的projection对象 */Projection projection = mapView.getProjection();for (int index = size() - 1; index >= 0; index--) {// 遍历,取得对应图标OverlayItem overlayItem = getItem(index);// 获取图标的标题String title = overlayItem.getTitle();/* * //Projection对象调用toPixels()方法得到由风景点得 经纬度地理坐标转化为在地图上的投影位置 */Point point = projection.toPixels(overlayItem.getPoint(), null);// 坐标圆形RectF oval = new RectF(point.x - mRadius, point.y - mRadius,point.x + mRadius, point.y + mRadius);Paint paint = new Paint();paint.setColor(Color.CYAN);paint.setAntiAlias(true);paint.setFakeBoldText(true);// 红色圆形Paint backpaint = new Paint();backpaint.setColor(Color.RED);backpaint.setAntiAlias(true);RectF backRectF = new RectF(point.x + 40 + mRadius, point.y - 3* mRadius, point.x + 65, point.y + 2 * mRadius);// 文字设置Paint paintText = new Paint();paintText.setColor(Color.BLUE);paintText.setTextSize(25);canvas.drawOval(oval, paint);canvas.drawRoundRect(backRectF, 10, 10, backpaint);canvas.drawText(title, point.x, point.y, paintText);}return super.draw(canvas, mapView, shadow, when);}}}

在程序中,注释已经很清楚了,在此就不多说了。

7、最后别忘记在AndroidManifest.xml文件中添加权限如下:

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.wyf.wpf"    android:versionCode="1"    android:versionName="1.0" >    <uses-sdk android:minSdkVersion="8" />    <application        android:icon="@drawable/ic_launcher"        android:label="@string/app_name" >        <activity            android:label="@string/app_name"            android:name=".ScenicDisplayActivity" >            <intent-filter >                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>        <uses-library android:name="com.google.android.maps" />    </application>    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />    <uses-permission android:name="android.permission.INTERNET" />    <uses-permission android:name="com.google.android.maps" /></manifest>

8、结束


更多相关文章

  1. android的wake_lock介绍
  2. Android(安卓)绘制文本垂直居中
  3. Android中动态改变控件的大小的一种方法
  4. Android(安卓)基于Zxing的扫码功能实现(二)
  5. Android的消息机制Handler
  6. Android(安卓)ListView 异步加载图片并缓存到本地
  7. Android(安卓)BroastCast的使用详解
  8. Android核心分析之一:分析方法论探讨之设计意图
  9. Android面试题整理(selfmade)——坚持每天回答一个

随机推荐

  1. devc++怎么调背景
  2. c语言规定在一个源程序中main函数的位置
  3. c语言统计单词个数的方法
  4. dev c++怎么改语言
  5. c语言逻辑运算符的优先级是怎样的
  6. c语言表达式语法规则是什么
  7. c++ vector用法详解
  8. 求水仙花数c语言代码怎么写
  9. c语言中break的用法
  10. 在c语言中的float是什么意思?