现在有这么一个需求:开启一个service服务,获取当前位置的经纬度数据,将获取的数据以广播的方式发送出去,注册广播的activity接收广播信息,并将接收到的数据在当前activity显示,如果当前位置发生变化,经纬度数据改变,获取改变后的经纬度数据,通过handler发送消息,更新ui界面,显示更新后的内容,请问这样子的demo该如何实现?
locationtool获取当前位置信息
android手机获取当前位置的方式:gps定位,wifi定位,基站定位,当前demo使用gps卫星定位,在locationtool中返回location、locationmanager两者对象,通过location提供的getlatitude()、getlongitude()读取经纬度数据,同时添加位置改变监听器mylocationlistener,具体代码如下:
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
|
package cn.teachcourse.utils; import android.app.activity; import android.content.context; import android.content.intent; import android.location.criteria; import android.location.location; import android.location.locationlistener; import android.location.locationmanager; import android.os.bundle; import android.provider.settings; import android.widget.toast; /* @author postmaster@teachcourse.cn @date 创建于:2016-1-22 */ public class locationtool { public location getlocation() { return mlocation; } public void setlocation(location location) { this .mlocation = location; } private context context; private location mlocation; private locationmanager mlocationmanager; public locationtool(context context) { super (); mlocationmanager = (locationmanager) context .getsystemservice(context.location_service); mlocation = mlocationmanager.getlastknownlocation(getprovider()); mlocationmanager.requestlocationupdates(locationmanager.gps_provider, 2000 , 10 , new mylocationlistener( this )); } // 获取location provider private string getprovider() { // 构建位置查询条件 criteria criteria = new criteria(); // 查询精度:高 criteria.setaccuracy(criteria.accuracy_fine); // 是否查询海拨:否 criteria.setaltituderequired( false ); // 是否查询方位角 : 否 criteria.setbearingrequired( false ); // 是否允许付费:是 criteria.setcostallowed( true ); // 电量要求:低 criteria.setpowerrequirement(criteria.power_low); // 返回最合适的符合条件的provider,第2个参数为true说明 , 如果只有一个provider是有效的,则返回当前provider return mlocationmanager.getbestprovider(criteria, true ); } public locationmanager getlocationmanager() { return mlocationmanager; } private locationlistener mlocationlistener = new locationlistener() { @override public void onstatuschanged(string provider, int status, bundle extras) { // todo auto-generated method stub } @override public void onproviderenabled(string provider) { location l = mlocationmanager.getlastknownlocation(provider); if (l != null ) { mlocation = l; } } @override public void onproviderdisabled(string provider) { mlocation = null ; } @override public void onlocationchanged(location location) { if (location != null ) { mlocation = location; } } }; public void closelocation() { if (mlocationmanager != null ) { if (mlocationmanager != null ) { mlocationmanager.removeupdates(mlocationlistener); mlocationlistener = null ; } mlocationmanager = null ; } } } |
mylocationlistener位置改变监听器
locationmanager对象调用requestlocationupdates(string provider, long mintime, float mindistance,locationlistener listener),在回调的方法中获取改变后的location对象,其中provider表示locationmanager.gps_provider,mintime表示最短时间间隔内更新位置信息(单位毫秒),mindistance表示最短距离内更新位置信息(单位米),mylocationlistener继承locationlistener,需要重写的方法如下:
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
|
package cn.teachcourse.utils; import android.location.location; import android.location.locationlistener; import android.os.bundle; /* @author postmaster@teachcourse.cn @date 创建于:2016-1-22 */ public class mylocationlistener implements locationlistener { private locationtool gpstool; /**构造方法,传入locationtool * @param gpstool */ public mylocationlistener(locationtool gpstool) { super(); this.gpstool = gpstool; } /** * 当前位置改变后,回调onlocationchanged方法,获取改变后的location对象 * */ @override public void onlocationchanged(location location) { if (location != null) { gpstool.setlocation(location); } } /** * 当provider状态改变时回调的方法,当前的provider无法读取位置信息或者provider从无法读取位置信息变为能够读取为信息被回调的方法 * */ @override public void onstatuschanged(string provider, int status, bundle extras) { // todo auto-generated method stub } /** * 当provider被用户允许开启,回调的onproviderenabled方法,比如:开启定位功能,回调该方法 * */ @override public void onproviderenabled(string provider) { location l = gpstool.getlocationmanager() .getlastknownlocation(provider); if (l != null) { gpstool.setlocation(l); } } /** * 当provider不被用户允许开启,回调的onproviderdisabled方法,比如:无法开启定位功能,回调该方法 * */ @override public void onproviderdisabled(string provider) { gpstool.setlocation( null ); } } |
locationservice服务读取位置信息
为什么要开启service呢?service和activity、fragment一样也有自己的生命周期,oncreate——>onstartcommand(onstart)——>onunbind——>onrebind——>ondestroy,在locationservice执行的操作是启动一个线程获取更新后的位置信息,并以广播的方式发送出去,具体代码如下:
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
|
package cn.teachcourse.utils; import android.app.activity; import android.app.service; import android.content.context; import android.content.intent; import android.location.location; import android.location.locationmanager; import android.os.ibinder; import android.provider.settings; import android.widget.toast; /* @author postmaster@teachcourse.cn @date 创建于:2016-1-22 */ public class locationservice extends service { private locationtool mgpstool = null ; private boolean threaddisable = false ; private final static string tag = locationservice. class .getsimplename(); @override public void oncreate() { // todo auto-generated method stub super .oncreate(); mgpstool = new locationtool( this ); startthread(); } private void startthread() { new thread( new runnable() { @override public void run() { while (!threaddisable) { try { thread.sleep( 1000 ); } catch (interruptedexception e) { e.printstacktrace(); } if (mgpstool != null ) { // 当结束服务时gps为空 // 获取经纬度 location location = mgpstool.getlocation(); // 发送广播 intent intent = new intent(); intent.putextra( "lat" , location == null ? "" : location.getlatitude() + "" ); intent.putextra( "lon" , location == null ? "" : location.getlongitude() + "" ); intent.setaction( "cn.teachcourse.utils.gpsservice" ); sendbroadcast(intent); } } } }).start(); } @override public void ondestroy() { super .ondestroy(); threaddisable = true ; if (mgpstool != null ) { mgpstool.closelocation(); mgpstool = null ; } } @override public ibinder onbind(intent intent) { return null ; } } |
mainactivity启动服务、注册广播、显示位置信息
在mainactivity需要做的事情有:第一启动locationservice服务,调用startservice()方法;第二注册广播接收器(broadcastreceiver),创建了一个内部类mybroadcastreceiver,继承broadcastreceiver,重写onreceive方法;第三获取经纬度数据,更新ui界面,显示当前位置信息,具体代码如下:
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
|
//启动服务 startservice( new intent( this , locationservice. class )); //注册广播 private class myreceiver extends broadcastreceiver { @override public void onreceive(context context, intent intent) { bundle bundle = intent.getextras(); string lon = bundle.getstring( "lon" ); string lat = bundle.getstring( "lat" ); if (!textutils.isempty(lon) && !textutils.isempty(lat)) { mlatitude = lat; mlongitude = lon; isobtainloc = true ; new thread( new runnable() { @override public void run() { message msg = new message(); msg.what = refresh_ui; // 发送消息,通知刷新界面 mhandler.sendmessage(msg); } }).start(); } } } //更新ui界面 private handler mhandler = new handler() { @override public void handlemessage(message msg) { // todo auto-generated method stub super .handlemessage(msg); switch (msg.what) { case refresh_ui: refreshui(); break ; default : break ; } } }; private void refreshui() { if (isobtainloc) { mtextview.settext( "目前经纬度\n经度:" + mlongitude + "\n纬度:" + mlatitude); mdialog.dismiss(); } } |
以上就是本文的全部内容,希望对大家学习android软件编程有所帮助。