现在有这么一个需求:开启一个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软件编程有所帮助。