懷着激動、興奮的心情,在這個漫天柳絮的季節寫下了這片博文,爲什麼呢,因爲困擾我很久的一個技術性的問題得到了解決,發次博文,供大家參觀、學習,同時,也以慰藉我長期困擾的心情,好了,廢話不再,言歸正傳,看看這到底是個什麼東西?
首先,簡單地介紹一下功能:1、離線地圖的加載;2、GPS的定位與顯示。文字比較模糊,看看實際的效果圖:
功能其實很簡單,下面解釋一下實現思路:
1、佈局
<?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" > <com.esri.android.map.MapView android:id="@+id/map" android:layout_width="fill_parent" android:layout_height="fill_parent"> </com.esri.android.map.MapView> <Button android:id="@+id/btnStartGps" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_marginLeft="10dp" android:layout_marginTop="10dp" android:text="GPS定位" /> </RelativeLayout>
佈局很簡單,一個mapView,用來顯示地圖;一個button,用來觸發GPS開始定位。
2、配置文件
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.esri.arcgis.android.samples.localtiledlayer" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="10" /> <uses-feature android:glEsVersion="0x00020000" android:required="true" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <application android:icon="@drawable/icon" android:label="@string/app_name" > <activity android:name="com.esri.arcgis.android.samples.localtiledlayer.LocalTiledLayer" android:configChanges="orientation" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name="com.baidu.location.f" android:enabled="true" android:process=":remote" > </service> </application> <uses-permission android:name="android.permission.GET_ACCOUNTS" /> <uses-permission android:name="android.permission.USE_CREDENTIALS" /> <uses-permission android:name="android.permission.MANAGE_ACCOUNTS" /> <uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" /> <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_NETWORK_STATE" > </uses-permission> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" > </uses-permission> <uses-permission android:name="android.permission.INTERNET" > </uses-permission> <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" > </uses-permission> <!-- <uses-permission android:name="android.permission.WRITE_APN_SETTINGS"></uses-permission> --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" > </uses-permission> <uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" /> <uses-permission android:name="android.permission.WAKE_LOCK" > </uses-permission> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_GPS" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.READ_CONTACTS" /> <uses-permission android:name="android.permission.CALL_PHONE" /> <uses-permission android:name="android.permission.READ_SMS" /> <uses-permission android:name="android.permission.SEND_SMS" /> <!-- SDK1.5需要android.permission.GET_TASKS權限判斷本程序是否爲當前運行的應用? --> <uses-permission android:name="android.permission.GET_TASKS" /> <uses-permission android:name="android.permission.CAMERA" > </uses-permission> <uses-permission android:name="android.permission.RECORD_AUDIO" > </uses-permission> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" > </uses-permission> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <uses-permission android:name="android.permission.BROADCAST_STICKY" /> <uses-permission android:name="android.permission.WRITE_SETTINGS" /> <!-- 來電消音 --> <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" > </uses-permission> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" /> <supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="false" android:resizeable="true" android:smallScreens="true" /> </manifest>
具體啥意思,自己去看看相關的資料吧,我在此不多做解釋。
3、activity實現
package com.esri.arcgis.android.samples.localtiledlayer; import android.app.Activity; import android.graphics.Color; import android.os.Bundle; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.Toast; import com.baidu.location.BDLocation; import com.baidu.location.BDLocationListener; import com.baidu.location.LocationClient; import com.baidu.location.LocationClientOption; import com.baidu.mapapi.BMapManager; import com.baidu.mapapi.MKGeneralListener; import com.baidu.mapapi.map.MKEvent; import com.esri.android.map.GraphicsLayer; import com.esri.android.map.MapView; import com.esri.android.map.ags.ArcGISLocalTiledLayer; import com.esri.core.geometry.GeometryEngine; import com.esri.core.geometry.Point; import com.esri.core.geometry.SpatialReference; import com.esri.core.map.Graphic; import com.esri.core.symbol.SimpleMarkerSymbol; import com.esri.core.symbol.SimpleMarkerSymbol.STYLE; public class LocalTiledLayer extends Activity { private MapView map = null; private ArcGISLocalTiledLayer local; //提示信息 private Toast toast; /** * GPS定位 */ private GraphicsLayer gLayerGps; private Point wgspoint; private Point mapPoint; private Button btnGPS; //定位SDK的核心類 private LocationClient mLocClient; //是否手動觸發請求定位 private boolean isRequest = true; //是否首次定位 private boolean isFirstLoc = true; //地圖顯示 private BMapManager mBMapMan = null; private int requestTime=0; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); map = (MapView) findViewById(R.id.map); mLocClient = new LocationClient(getApplicationContext()); mLocClient.registerLocationListener(new BDLocationListenerImpl());//註冊定位監聽接口 /** * LocationClientOption 該類用來設置定位SDK的定位方式。 */ LocationClientOption option = new LocationClientOption(); option.setOpenGps(true); //打開GPRS option.setAddrType("all");//返回的定位結果包含地址信息 option.setCoorType("bd09ll");//返回的定位結果是百度經緯度,默認值gcj02 option.setPriority(LocationClientOption.GpsFirst); // 設置GPS優先 option.setScanSpan(1000); //設置發起定位請求的間隔時間爲1s option.disableCache(true);//啓用緩存定位 mLocClient.setLocOption(option); //設置定位參數 local = new ArcGISLocalTiledLayer("file:///storage/sdcard0/arcgis/base_map.tpk"); map.addLayer(local); gLayerGps = new GraphicsLayer(); map.addLayer(gLayerGps); //開始定位按鈕 btnGPS=(Button)findViewById(R.id.btnStartGps); btnGPS.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { mLocClient.start();//調用此方法開始定位 requestLocation(); } }); } public void requestLocation() { isRequest = true; if(mLocClient != null && mLocClient.isStarted()) { showToast("GPS正在定位……"); mLocClient.requestLocation(); } else { Log.d("log", "locClient is null or not started"); } } public class MKGeneralListenerImpl implements MKGeneralListener { /** * 一些網絡狀態的錯誤處理回調函數 */ @Override public void onGetNetworkState(int iError) { if (iError == MKEvent.ERROR_NETWORK_CONNECT) { showToast("您的網絡出錯啦!"); } } /** * 授權錯誤的時候調用的回調函數 */ @Override public void onGetPermissionState(int iError) { if (iError == MKEvent.ERROR_PERMISSION_DENIED) { showToast("API KEY錯誤, 請檢查!"); } } } private void showToast(String msg) { if(toast == null) { toast = Toast.makeText(this, msg, Toast.LENGTH_SHORT); } else { toast.setText(msg); toast.setDuration(Toast.LENGTH_SHORT); } toast.show(); } /** * 將GPS點標註在地圖上 * @param 緯度 * @param 經度 */ public void ShowGpsOnMap(double lon,double lat){ //清空定位圖層 gLayerGps.removeAll(); //接收到的GPS的信號X(lat),Y(lon) double locx = lon; double locy = lat; wgspoint = new Point(locx, locy); mapPoint = (Point) GeometryEngine.project(wgspoint,SpatialReference.create(4326),map.getSpatialReference()); //圖層的創建 Graphic graphic = new Graphic(mapPoint,new SimpleMarkerSymbol(Color.RED,18,STYLE.CIRCLE)); gLayerGps.addGraphic(graphic); } public class BDLocationListenerImpl implements BDLocationListener { /** * 接收異步返回的定位結果,參數是BDLocation類型參數 */ @Override public void onReceiveLocation(BDLocation location) { if (location == null) { return; } StringBuffer sb = new StringBuffer(256); sb.append("time : "); sb.append(location.getTime()); sb.append("\nerror code : "); sb.append(location.getLocType()); sb.append("\nlatitude : "); sb.append(location.getLatitude()); sb.append("\nlontitude : "); sb.append(location.getLongitude()); sb.append("\nradius : "); sb.append(location.getRadius()); if (location.getLocType() == BDLocation.TypeGpsLocation) { sb.append("\nspeed : "); sb.append(location.getSpeed()); sb.append("\nsatellite : "); sb.append(location.getSatelliteNumber()); } else if (location.getLocType() == BDLocation.TypeNetWorkLocation) { sb.append("\naddr : "); sb.append(location.getAddrStr()); } Log.e("log", sb.toString()); if(isFirstLoc || isRequest) { isRequest = false; } isFirstLoc = false; double lat=location.getLatitude(); double lon=location.getLongitude(); ShowGpsOnMap(lon,lat); } @Override public void onReceivePoi(BDLocation arg0) { // TODO Auto-generated method stub } } }
相對來說,註釋也是很清楚地,就不做多解釋,思路大概是:
顯示地圖——》接收位置信息,獲取經緯度——》將經緯度轉換爲點在地圖上標繪