随笔 - 227  文章 - 0  评论 - 13  阅读 - 19万 

怀着激动、兴奋的心情,在这个漫天柳絮的季节写下了这片博文,为什么呢,因为困扰我很久的一个技术性的问题得到了解决,发次博文,供大家参观、学习,同时,也以慰藉我长期困扰的心情,好了,废话不再,言归正传,看看这到底是个什么东西?

 

首先,简单地介绍一下功能: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实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
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
             
        }
    }
}

  相对来说,注释也是很清楚地,就不做多解释,思路大概是:

 

显示地图——》接收位置信息,获取经纬度——》将经纬度转换为点在地图上标绘

posted on   LZU-GIS  阅读(1606)  评论(2编辑  收藏  举报
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示