关于在Android客户端上百度地图的基本功能实现

转帖请贴明出处:http://blog.csdn.net/yezisuifengbiao/article/details/13019049

首先,毋庸置疑的肯定是先申请百度地图的KEY。

至于申请方法,相信大家都知道。这点就不详述了。

其次,是下载相关的SDK,传送门:http://developer.baidu.com/map/sdkandev-download.htm

然后便是打开开发环境,新建工程,博主使用的是Eclipse.

这工程是从之前公司的项目里分离出来的,所以我写的是Fragment页面的。

下面是我项目的结构:


新建完工程,别忙着干其他,把下载好的SDK,先放到libs文件夹中:


然后在项目 右键---Build Path---Configure Build Path---Libraries---Add JARs 选择 baidumapapi_v2_1_0.jar 这个包---OK

其次,我们需要在AndroidManifest.xml文件里面,添加,我们所需的权限信息。这点,在百度地图的API页面有提到:

 <!-- 使用网络功能所需权限 -->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" >
    </uses-permission>
    <uses-permission android:name="android.permission.INTERNET" >
    </uses-permission>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" >
    </uses-permission>
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" >
    </uses-permission>
    <!-- SDK离线地图和cache功能需要读写外部存储器 -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" >
    </uses-permission>
    <!-- 获取设置信息和详情页直接拨打电话需要以下权限 -->
    <uses-permission android:name="android.permission.READ_PHONE_STATE" >
    </uses-permission>
    <uses-permission android:name="android.permission.CALL_PHONE" >
    </uses-permission>
    <!-- 使用定位功能所需权限,demo已集成百度定位SDK,不使用定位功能可去掉以下6项 -->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" >
    </uses-permission>

    <permission android:name="android.permission.BAIDU_LOCATION_SERVICE" >
    </permission>

    <uses-permission android:name="android.permission.BAIDU_LOCATION_SERVICE" >
    </uses-permission>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" >
    </uses-permission>
    <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" >
    </uses-permission>
    <uses-permission android:name="android.permission.ACCESS_GPS" />

配置Activity:

<activity
            android:name="com.BaiduMapDemo.Activity.MainActivity"
            android:configChanges="orientation|keyboardHidden"
            android:label="@string/app_name"
            android:screenOrientation="portrait" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

添加屏幕及版本支持:

<supports-screens
        android:anyDensity="true"
        android:largeScreens="true"
        android:normalScreens="true"
        android:resizeable="true"
        android:smallScreens="true" />

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />


我们需要自定义一个类,继承Appliction,用于存放一些全局的和上下文的变量与方法:

下面是BaiduMapApplication.java的内容:

package com.BaiduMapDemo.Activity;

import android.app.Application;
import android.content.Context;
import android.widget.Toast;
import com.baidu.mapapi.BMapManager;
import com.baidu.mapapi.MKGeneralListener;
import com.baidu.mapapi.map.MKEvent;

public class BaiduMapApplication extends Application {

	public static BaiduMapApplication mInstance = null;
	public boolean m_bKeyRight = true;
	BMapManager mBMapManager = null;

	public static final String strKey = "此处填写在百度地图申请的授权KEY";

	@Override
	public void onCreate() {
		super.onCreate();
		mInstance = this;
		initEngineManager(this);
	}

	@Override
	// 建议在您app的退出之前调用mapadpi的destroy()函数,避免重复初始化带来的时间消耗
	public void onTerminate() {
		// TODO Auto-generated method stub
		if (mBMapManager != null) {
			mBMapManager.destroy();
			mBMapManager = null;
		}
		super.onTerminate();
	}

	public void initEngineManager(Context context) {
		if (mBMapManager == null) {
			mBMapManager = new BMapManager(context);
		}

		if (!mBMapManager.init(strKey, new MyGeneralListener())) {
			Toast.makeText(
					BaiduMapApplication.getInstance().getApplicationContext(),
					"BMapManager  初始化错误!", Toast.LENGTH_LONG).show();
		}
	}

	public static BaiduMapApplication getInstance() {
		return mInstance;
	}

	// 常用事件监听,用来处理通常的网络错误,授权验证错误等
	static class MyGeneralListener implements MKGeneralListener {

		@Override
		public void onGetNetworkState(int iError) {
			if (iError == MKEvent.ERROR_NETWORK_CONNECT) {
				Toast.makeText(
						BaiduMapApplication.getInstance().getApplicationContext(),
						"您的网络出错啦!", Toast.LENGTH_LONG).show();
			} else if (iError == MKEvent.ERROR_NETWORK_DATA) {
				Toast.makeText(
						BaiduMapApplication.getInstance().getApplicationContext(),
						"输入正确的检索条件!", Toast.LENGTH_LONG).show();
			}
			// ...
		}

		@Override
		public void onGetPermissionState(int iError) {
			if (iError == MKEvent.ERROR_PERMISSION_DENIED) {
				// 授权Key错误:
				Toast.makeText(
						BaiduMapApplication.getInstance().getApplicationContext(),
						"授权Key错误!", Toast.LENGTH_LONG).show();
				BaiduMapApplication.getInstance().m_bKeyRight = false;
			}
		}
	}
}

自定义了继承Appliction类,需要在AndroidManifest.xml添加支持:

 <application
        android:name="com.BaiduMapDemo.Activity.BaiduMapApplication"
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" ></application>

这些工作做完,我们便可以真正的来实现我们的地图功能了。由于我是用Fragment效果来实现的,所以我必须先写一个继承FragmentActivity的类来管理Fragment,但在此之前,我们要先写界面:

主页面MainActivity:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <RelativeLayout
        android:id="@+id/rel_weizhan"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="visible" >

        <RelativeLayout
            android:id="@+id/RelativeLayout01"
            android:layout_width="fill_parent"
            android:layout_height="@dimen/action_bar_height"
            android:layout_alignParentLeft="true"
            android:layout_alignParentTop="true"
            android:background="@drawable/landing_title" >

            <TextView
                android:id="@+id/TextView01"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerHorizontal="true"
                android:layout_centerVertical="true"
                android:text="@string/title_activity_baidu_map"
                android:textColor="@color/white"
                android:textSize="@dimen/title_size" />
        </RelativeLayout>

        <RelativeLayout
            android:id="@+id/weizhan_tab"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@+id/RelativeLayout01" >

            <LinearLayout
                android:id="@+id/line"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentLeft="true"
                android:background="@drawable/weizhan"
                android:orientation="horizontal" >

                <TextView
                    android:id="@+id/txt_Map"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:layout_weight="1"
                    android:gravity="center"
                    android:text="@string/map_tab_one" />

                <TextView
                    android:id="@+id/txt_Contact"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:layout_weight="1"
                    android:gravity="center"
                    android:text="@string/map_tab_two" />
            </LinearLayout>

            <RelativeLayout
                android:id="@+id/rel_cursor_bg"
                android:layout_width="wrap_content"
                android:layout_height="@dimen/cursor_bg"
                android:layout_below="@+id/line"
                android:background="@drawable/weizhan_cursor_bg" >
            </RelativeLayout>

            <ImageView
                android:id="@+id/img_cursor"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_above="@+id/rel_cursor_bg"
                android:layout_alignBottom="@+id/rel_cursor_bg"
                android:src="@drawable/weizhan_cursor" />
        </RelativeLayout>

        <android.support.v4.view.ViewPager
            android:id="@+id/vPager"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_below="@+id/weizhan_tab"
            android:layout_gravity="center"
            android:flipInterval="30"
            android:persistentDrawingCache="animation" />
    </RelativeLayout>

</RelativeLayout>

接着,便是MainActivity类的内容。

注释都写得很清楚在里面了:

package com.BaiduMapDemo.Activity;

import java.util.ArrayList;
import com.BaiduMapDemo.adapter.MyPagerAdapter;
import com.example.baidumapdemo.R;
import android.os.Bundle;
import android.graphics.BitmapFactory;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.widget.ImageView;
import android.widget.TextView;

public class MainActivity extends FragmentActivity implements OnClickListener {

	/**
	 * ViewPager是google SDk中自带的一个附加包的一个类,可以用来实现屏幕间的切换。android-support-v4.jar
	 */
	private ViewPager mPager;// 页卡内容
	/**
	 * 动画图片
	 */
	private ImageView cursor;
	/**
	 * 页卡头标
	 */
	private TextView txt_Map, txt_Contact;
	/**
	 * tab头的宽度减去动画图片的宽度再除以2(保证动画图片相对tab头居中)
	 */
	private int offsetX;
	/**
	 * 当前页卡编号
	 */
	private int currIndex = 0;
	/**
	 * 每个tab头的宽度
	 */
	private int tabWidth;
	/**
	 * 动画图片宽度
	 */
	private int ivCursorWidth;
	private ArrayList<Fragment> fragmentsList;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.activity_main);

		InitViewPager();
		InitTextView();
		InitImageView();

	}

	/**
	 * 实例化ViewPager
	 */
	private void InitViewPager() {
		mPager = (ViewPager) findViewById(R.id.vPager);
		fragmentsList = new ArrayList<Fragment>();
		/**
		 * 默认加载左右各0个页面
		 */
		mPager.setOffscreenPageLimit(0);
		/**
		 * 添加两个页面
		 */
		Fragment BaiduMap = new BaiduMapActivity();
		Fragment Contact = new ContactActivity();
		fragmentsList.add(BaiduMap);
		fragmentsList.add(Contact);
		/**
		 * 将FragmentList绑定在ViewPager上
		 */
		mPager.setAdapter(new MyPagerAdapter(getSupportFragmentManager(),
				fragmentsList));
		/**
		 * 设置默认在第一页
		 */
		mPager.setCurrentItem(0);
		mPager.setOnPageChangeListener(new MyOnPageChangeListener());
	}

	/**
	 * 实例化TextView
	 */
	private void InitTextView() {

		txt_Map = (TextView) findViewById(R.id.txt_Map);
		txt_Contact = (TextView) findViewById(R.id.txt_Contact);

		txt_Map.setOnClickListener(new MyOnClickListener(0));
		txt_Contact.setOnClickListener(new MyOnClickListener(1));

	}

	/**
	 * 实例化ImageView
	 */
	private void InitImageView() {
		cursor = (ImageView) findViewById(R.id.img_cursor);
		DisplayMetrics dm = getResources().getDisplayMetrics();
		/**
		 * 获取分辨率
		 */
		int screenW = dm.widthPixels;
		/**
		 * 获取图片宽度
		 */
		ivCursorWidth = BitmapFactory.decodeResource(getResources(),
				R.drawable.weizhan_cursor).getWidth();

		tabWidth = screenW / fragmentsList.size();
		if (ivCursorWidth > tabWidth) {
			cursor.getLayoutParams().width = tabWidth;
			ivCursorWidth = tabWidth;
		}
		offsetX = (tabWidth - ivCursorWidth) / 2;
	}

	/**
	 * 头标点击监听
	 */
	public class MyOnClickListener implements View.OnClickListener {
		private int index = 0;

		public MyOnClickListener(int i) {
			index = i;
		}

		@Override
		public void onClick(View v) {
			mPager.setCurrentItem(index);
		}
	};

	/**
	 * 页卡切换监听
	 */
	public class MyOnPageChangeListener implements OnPageChangeListener {

		@Override
		public void onPageSelected(int arg0) {
			/**
			 * 游标动画效果
			 */
			Animation animation = new TranslateAnimation(tabWidth * currIndex
					+ offsetX, tabWidth * arg0 + offsetX, 0, 0);
			currIndex = arg0;
			/**
			 * True:图片停在动画结束位置
			 */
			animation.setFillAfter(true);
			animation.setDuration(100);
			cursor.startAnimation(animation);
		}

		@Override
		public void onPageScrolled(int arg0, float arg1, int arg2) {
		}

		@Override
		public void onPageScrollStateChanged(int arg0) {
		}
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		default:
			break;
		}
	}
}
Fragment效果其实很多人并不陌生,因为它很常用也很好用,不过主要还是为了照顾那些刚刚接触Android的新手,所以我把注释尽可能的写得清楚。

因为做的是Fragment效果,所以我添加了两个页面害羞其中一个便是地图的页面,另一个其实是闲置的安静老样子,我们需要先实现界面。下面贴出BaiduMapActivity这个类的界面。

地图页面:

<?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" >

    <com.baidu.mapapi.map.MapView
        android:id="@+id/map_bmapsView"
        android:layout_width="fill_parent"
        android:layout_height="0dp"
        android:layout_weight="1.17"
        android:clickable="true" />

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/celebration_service_map_menu" >

        <Spinner
            android:id="@+id/spr_campus"
            style="@style/spinner_style"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignBottom="@+id/btn_bus"
            android:layout_alignParentRight="true"
            android:layout_alignTop="@+id/btn_bus"
            android:layout_centerInParent="true"
            android:layout_marginLeft="15dp"
            android:layout_marginRight="10dp"
            android:layout_toRightOf="@+id/btn_walk" />

        <Button
            android:id="@+id/btn_bus"
            style="@style/bus_style"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_centerInParent="true" />

        <Button
            android:id="@+id/btn_drive"
            style="@style/car_style"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:layout_toRightOf="@+id/btn_bus" />

        <Button
            android:id="@+id/btn_walk"
            style="@style/walk_style"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:layout_toRightOf="@+id/btn_drive" />
    </RelativeLayout>

</LinearLayout>

准备贴出代码的时候,猛然发现实现地图的类的内容写的比较多,代码太长,就不全部贴出来了,不过我会放出下载链接供大家下载参考。


我实现的是基本的导航功能,包含了公交、驾车、步行的各种交通策略。至于导航地点,我定了三个点,分别是天安门、东方明珠及广州塔。在这里给大家推荐个网站,非广告!http://www.gpsspg.com/maps.htm专门用于查询经纬度的。

贴一个行程策略的例子给大家看看:

/**
 * 行程策略。详见API com.baidu.mapapi.
 * search.MKSearch类
 */
strategy = MKSearch.EBUS_NO_SUBWAY;
start.pt = startPoint;
/**
 * 设置起点为地图中心点
 */
mMapController.setCenter(start.pt);
end.pt = endPoint;
mSearch.setTransitPolicy(strategy);
mSearch.transitSearch("广州",start, end);

MKSearch类里面,有根据不同行车策略给出不同的方案,只要调用相对于的函数就可以了。

确定了行程的策略,那就是路线问题了,要知道怎么去目的地,首先得知道自己的位置,及目的地的位置。自己的位置是用定位获得,目的地位置,在我这个Demo里面,是写死,提供选择的。这一点,各位可以根据自己的需求去更改。在这里得说一下,如果你选择的是公交车的行程方案的话


mSearch.transitSearch("广州",start, end);//城市名必须填写

我们看API,里面的这么说的:

API:

transitSearch

public int transitSearch(java.lang.String city, MKPlanNode start, MKPlanNode end)

公交路线搜索.

异步函数,返回结果在MKSearchListener里的onGetTransitRouteResult方法通知 参数: city - 城市名,用于在哪个城市内进行检索 start - 检索的起点,可通过关键字,坐标两种方式指定 end - 检索的终点,可通过关键字,坐标两种方式指定 返回: 成功返回0,否则返回-1 setTransitPolicy public int setTransitPolicy(int policy)

设置路线规划策略.

参数为策略常量。对下次搜索有效 参数: policy - EBUS_TIME_FIRST:时间优先;EBUS_TRANSFER_FIRST:少换乘;EBUS_WALK_FIRST:少步行;EBUS_NO_SUBWAY: 非地铁 返回: 成功返回0,否则返回-1


也就说,我们的起点与终点,必须在同一个城市才能使用公交车,那么这个城市的地点(java.lang.String city)其实我们可以根据定位信息来获取,百度地图的开发者平台上一个Demo,是专门讲定位的,大家可以自行去下载,参考。在这里,为了简便,我就自己填写了所在的城市,呵呵。



点我-下载源码

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值