使用Google地图

新建RunMapActivity显示地图

public class RunMapActivity extends SingleFragmentActivity {
    public static final String EXTRA_RUN_ID = "com.huangfei.runtracker.run_id";

    @Override
    protected Fragment createFragment() {
        long runId = getIntent().getLongExtra(EXTRA_RUN_ID, -1);
        if (runId != -1) {
            return RunMapFragment.newInstance(runId);
        } else {
            return new RunMapFragment();
        }
    }

}
package com.huangfei.runtracker;

import java.util.Date;

import android.database.Cursor;
import android.location.Location;
import android.os.Bundle;
import android.support.v4.app.LoaderManager;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.Loader;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.PolylineOptions;
import com.huangfei.runtracker.RunDatabaseHelper.LocationCursor;

/**
 * MapFragment与SupportMapFragment是Maps API的两个类。通过创建和两个类的子类,我们可以方便地配置MapView和
 * GooleMap(与MapView关联的模型对象)。可利用GooleMap对地图进行各种附加配置。
 */
public class RunMapFragment extends SupportMapFragment implements
        LoaderCallbacks<Cursor> {
    private static final String ARG_RUN_ID = "RUN_ID";
    private static final int LOAD_LOCATIONS = 0;

    private GoogleMap mGoogleMap;
    private LocationCursor mLocationCursor;

    public static RunMapFragment newInstance(long runId) {
        Bundle bundle = new Bundle();
        bundle.putLong(ARG_RUN_ID, runId);
        RunMapFragment fragment = new RunMapFragment();
        fragment.setArguments(bundle);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Bundle args = getArguments();
        if (args != null) {
            long runId = args.getLong(ARG_RUN_ID, -1);
            if (runId != -1) {
                LoaderManager lm = getLoaderManager();
                lm.initLoader(LOAD_LOCATIONS, args, this);
            }
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View view = super.onCreateView(inflater, container, savedInstanceState);

        mGoogleMap = getMap();
        // 允许用户在地图上查看并导航至自身地理位置
        mGoogleMap.setMyLocationEnabled(true);

        return view;
    }

    private void updateUI() {
        if (mGoogleMap == null || mLocationCursor == null)
            return;

        //PolylineOptions实例创建用于地图的线条
        PolylineOptions line = new PolylineOptions();
        //LatLngBounds.Builder实例用于在所有数据收集完时,创建一个供地图缩放的包围框
        LatLngBounds.Builder latLngBuilder = new LatLngBounds.Builder();
        mLocationCursor.moveToFirst();
        while (!mLocationCursor.isAfterLast()) {
            Location loc = mLocationCursor.getLocation();
            LatLng latLng = new LatLng(loc.getLatitude(), loc.getLongitude());

            /**
             * 添加地图标识,显示旅程的开始和结束点,并为地图标注上相关文字信息,实现用户点击地图标注时弹出一个信息框。
             */
            if (mLocationCursor.isFirst()) {
                String startDate = new Date(loc.getTime()).toString();
                MarkerOptions startMarkerOptions = new MarkerOptions()
                    .position(latLng)//位置
                    .title(getResources().getString(R.string.run_start))//标题
                    .snippet(getResources().getString(R.string.run_started_at_format, startDate));//位置简介文字
                mGoogleMap.addMarker(startMarkerOptions);
            } else if (mLocationCursor.isLast()) {
                String endDate = new Date(loc.getTime()).toString();
                MarkerOptions finishMarkerOptions = new MarkerOptions()
                    .position(latLng)
                    .title(getResources().getString(R.string.run_finish))
                    .snippet(getResources().getString(R.string.run_finished_at_format, endDate));
                mGoogleMap.addMarker(finishMarkerOptions);
            }

            line.add(latLng);
            latLngBuilder.include(latLng);
            mLocationCursor.moveToNext();
        }
        //将线条绘制到地图上
        mGoogleMap.addPolyline(line);
        //缩放地图以显示整个旅程路线
        Display display = getActivity().getWindowManager().getDefaultDisplay();
        /**
         * “camera”负责处理地图上移动的操作。打包在CameraUpdate实例中的移动指令是用来调整camera的,
         * 我们将其传入moveCamera(CameraUpdate)方法实现在地图上移动。而CameraUpdateFactory
         * 的newLatLngBounds(LatLngBounds, int, int, int)方法则负责创建一个实例,将camera
         * 的移动限制在刚添加的包围框内。
         * 
         * 这里,以像素为单位,我们传入当前屏幕尺寸作为地图的近似大小尺寸。为使两者完美契合,我们指定了一个15单位像素的填充。
         * 相较于newLatLngBounds(LatLngBounds, int, int, int)方法,还有一个简单版本的newLatLngBounds(LatLngBounds, int)
         * 方法可供使用。但是,如果在MapView通过绘制过程完成自身尺寸确定之前就调用该简单版本的方法,它会抛出IllegalStateException异常。
         * 既然无法保证调用updateUI()方法时MapView能否准备就绪,因此只能使用屏幕尺寸作为安全的假想值了。
         */
        CameraUpdate movement = CameraUpdateFactory.newLatLngBounds(latLngBuilder.build(),
                display.getWidth(), display.getHeight(), 15);
        mGoogleMap.moveCamera(movement);
    }

    @Override
    public Loader<Cursor> onCreateLoader(int arg0, Bundle bundle) {
        return new LocationListCursorLoader(getActivity(), bundle.getLong(
                ARG_RUN_ID, -1));
    }

    @Override
    public void onLoadFinished(Loader<Cursor> arg0, Cursor cursor) {
        mLocationCursor = (LocationCursor) cursor;
        updateUI();
    }

    /**
     * 数据加载完毕后,onLoaderReset(Loader<Cursor>)实现方法负责关闭cursor并清除对其的引用。
     * 正常情况下,应在用户离开地图fragment界面后,LoaderManager停止loader时调用该方法。
     */
    @Override
    public void onLoaderReset(Loader<Cursor> cursor) {
        mLocationCursor.close();
        mLocationCursor = null;
    }
}

在manifest配置文件中注册

<permission
        android:name="com.huangfei.runtracker.permission.MAPS_RECEIVE"
        android:protectionLevel="signature" />

    <uses-permission android:name="com.huangfei.runtracker.permission.MAPS_RECEIVE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

<uses-feature
        android:glEsVersion="0x00020000"
        android:required="true" />

....

 <activity
            android:name=".RunMapActivity"
            android:label="@string/app_name" />
        <meta-data
            android:name="com.google.android.maps.v2.API_KEY"
            android:value="AIzaSyD2rZZS68wqm9MgbJJKaeE1zcp5YwIbe00" />

以上权限中,以MAPS_RECEIVE结尾的使用权限,需添加该应用的全路径包名。

代码地址

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值