Android Service获取当前位置GPS+基站.docx
《Android Service获取当前位置GPS+基站.docx》由会员分享,可在线阅读,更多相关《Android Service获取当前位置GPS+基站.docx(35页珍藏版)》请在冰豆网上搜索。
AndroidService获取当前位置GPS+基站
AndroidService获取当前位置(GPS+基站)
需求详情:
1)、Service中每隔1秒执行一次定位操作(GPS+基站)
2)、定位的结果实时显示在界面上(要求得到经度、纬度)
技术支持:
1)、获取经纬度
通过GPS+基站获取经纬度,先通过GPS来获取,如果为空改用基站进行获取–>GPS+基站(基站获取支持联通、电信、移动)。
2)、实时获取经纬度
为了达到实时获取经纬度,需在后台启动获取经纬度的Service,然后把经纬度数据通过广播发送出去,在需要的地方进行广播注册(比如在Activity中注册广播,显示在界面中)–>涉及到Service+BroadcastReceiver+Activity+Thread等知识点。
备注:
本文注重实践,如有看不懂的,先去巩固下知识点,可以去看看我前面写的几篇文章。
1、CellInfo实体类–>基站信息
packagecom.ljq.activity;
/**
*基站信息
*
*@authorjiqinlin
*
*/
publicclassCellInfo{
/**基站id,用来找到基站的位置*/
privateintcellId;
/**移动国家码,共3位,中国为460,即imsi前3位*/
privateStringmobileCountryCode="460";
/**移动网络码,共2位,在中国,移动的代码为00和02,联通的代码为01,电信的代码为03,即imsi第4~5位*/
privateStringmobileNetworkCode="0";
/**地区区域码*/
privateintlocationAreaCode;
/**信号类型[选gsm|cdma|wcdma]*/
privateStringradioType="";
publicCellInfo(){
}
publicintgetCellId(){
returncellId;
}
publicvoidsetCellId(intcellId){
this.cellId=cellId;
}
publicStringgetMobileCountryCode(){
returnmobileCountryCode;
}
publicvoidsetMobileCountryCode(StringmobileCountryCode){
this.mobileCountryCode=mobileCountryCode;
}
publicStringgetMobileNetworkCode(){
returnmobileNetworkCode;
}
publicvoidsetMobileNetworkCode(StringmobileNetworkCode){
this.mobileNetworkCode=mobileNetworkCode;
}
publicintgetLocationAreaCode(){
returnlocationAreaCode;
}
publicvoidsetLocationAreaCode(intlocationAreaCode){
this.locationAreaCode=locationAreaCode;
}
publicStringgetRadioType(){
returnradioType;
}
publicvoidsetRadioType(StringradioType){
this.radioType=radioType;
}
}
2、Gps类–>Gps封装类,用来获取经纬度
packagecom.ljq.activity;
importandroid.content.Context;
importandroid.location.Criteria;
importandroid.location.Location;
importandroid.location.LocationListener;
importandroid.location.LocationManager;
importandroid.os.Bundle;
publicclassGps{
privateLocationlocation=null;
privateLocationManagerlocationManager=null;
privateContextcontext=null;
/**
*初始化
*
*@paramctx
*/
publicGps(Contextctx){
context=ctx;
locationManager=(LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
location=locationManager.getLastKnownLocation(getProvider());
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,2000,10,locationListener);
}
//获取LocationProvider
privateStringgetProvider(){
//构建位置查询条件
Criteriacriteria=newCriteria();
//查询精度:
高
criteria.setAccuracy(Criteria.ACCURACY_FINE);
//是否查询海拨:
否
criteria.setAltitudeRequired(false);
//是否查询方位角:
否
criteria.setBearingRequired(false);
//是否允许付费:
是
criteria.setCostAllowed(true);
//电量要求:
低
criteria.setPowerRequirement(Criteria.POWER_LOW);
//返回最合适的符合条件的provider,第2个参数为true说明,如果只有一个provider是有效的,则返回当前provider
returnlocationManager.getBestProvider(criteria,true);
}
privateLocationListenerlocationListener=newLocationListener(){
//位置发生改变后调用
publicvoidonLocationChanged(Locationl){
if(l!
=null){
location=l;
}
}
//provider被用户关闭后调用
publicvoidonProviderDisabled(Stringprovider){
location=null;
}
//provider被用户开启后调用
publicvoidonProviderEnabled(Stringprovider){
Locationl=locationManager.getLastKnownLocation(provider);
if(l!
=null){
location=l;
}
}
//provider状态变化时调用
publicvoidonStatusChanged(Stringprovider,intstatus,Bundleextras){
}
};
publicLocationgetLocation(){
returnlocation;
}
publicvoidcloseLocation(){
if(locationManager!
=null){
if(locationListener!
=null){
locationManager.removeUpdates(locationListener);
locationListener=null;
}
locationManager=null;
}
}
}
3、GpsService服务类
packagecom.ljq.activity;
importjava.util.ArrayList;
importandroid.app.Service;
importandroid.content.Intent;
importandroid.location.Location;
importandroid.os.IBinder;
importandroid.util.Log;
publicclassGpsServiceextendsService{
ArrayListcellIds=null;
privateGpsgps=null;
privatebooleanthreadDisable=false;
privatefinalstaticStringTAG=GpsService.class.getSimpleName();
@Override
publicvoidonCreate(){
super.onCreate();
gps=newGps(GpsService.this);
cellIds=UtilTool.init(GpsService.this);
newThread(newRunnable(){
@Override
publicvoidrun(){
while(!
threadDisable){
try{
Thread.sleep(1000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
if(gps!
=null){//当结束服务时gps为空
//获取经纬度
Locationlocation=gps.getLocation();
//如果gps无法获取经纬度,改用基站定位获取
if(location==null){
Log.v(TAG,"gpslocationnull");
//2.根据基站信息获取经纬度
try{
location=UtilTool.callGear(GpsService.this,cellIds);
}catch(Exceptione){
location=null;
e.printStackTrace();
}
if(location==null){
Log.v(TAG,"celllocationnull");
}
}
//发送广播
Intentintent=newIntent();
intent.putExtra("lat",location==null?
"":
location.getLatitude()+"");
intent.putExtra("lon",location==null?
"":
location.getLongitude()+"");
intent.setAction("com.ljq.activity.GpsService");
sendBroadcast(intent);
}
}
}
}).start();
}
@Override
publicvoidonDestroy(){
threadDisable=true;
if(cellIds!
=null&&cellIds.size()>0){
cellIds=null;
}
if(gps!
=null){
gps.closeLocation();
gps=null;
}
super.onDestroy();
}
@Override
publicIBinderonBind(Intentarg0){
returnnull;
}
}
4、GpsActivity–>在界面上实时显示经纬度数据
packagecom.ljq.activity;
importandroid.app.Activity;
importandroid.content.BroadcastReceiver;
importandroid.content.Context;
importandroid.content.Intent;
importandroid.content.IntentFilter;
importandroid.location.Location;
importandroid.location.LocationManager;
importandroid.os.Bundle;
importandroid.util.Log;
importandroid.widget.EditText;
importandroid.widget.Toast;
publicclassGpsActivityextendsActivity{
privateDoublehomeLat=26.0673834d;//宿舍纬度
privateDoublehomeLon=119.3119936d;//宿舍经度
privateEditTexteditText=null;
privateMyReceiverreceiver=null;
privatefinalstaticStringTAG=GpsActivity.class.getSimpleName();
@Override
publicvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
editText=(EditText)findViewById(R.id.editText);
//判断GPS是否可用
Log.i(TAG,UtilTool.isGpsEnabled((LocationManager)getSystemService(Context.LOCATION_SERVICE))+"");
if(!
UtilTool.isGpsEnabled((LocationManager)getSystemService(Context.LOCATION_SERVICE))){
Toast.makeText(this,"GSP当前已禁用,请在您的系统设置屏幕启动。
",Toast.LENGTH_LONG).show();
IntentcallGPSSettingIntent=newIntent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(callGPSSettingIntent);
return;
}
//启动服务
startService(newIntent(this,GpsService.class));
//注册广播
receiver=newMyReceiver();
IntentFilterfilter=newIntentFilter();
filter.addAction("com.ljq.activity.GpsService");
registerReceiver(receiver,filter);
}
//获取广播数据
privateclassMyReceiverextendsBroadcastReceiver{
@Override
publicvoidonReceive(Contextcontext,Intentintent){
Bundlebundle=intent.getExtras();
Stringlon=bundle.getString("lon");
Stringlat=bundle.getString("lat");
if(lon!
=null&&!
"".equals(lon)&&lat!
=null&&!
"".equals(lat)){
doubledistance=getDistance(Double.parseDouble(lat),
Double.parseDouble(lon),homeLat,homeLon);
editText.setText("目前经纬度\n经度:
"+lon+"\n纬度:
"+lat+"\n离宿舍距离:
"+java.lang.Math.abs(distance));
}else{
editText.setText("目前经纬度\n经度:
"+lon+"\n纬度:
"+lat);
}
}
}
@Override
protectedvoidonDestroy(){
//注销服务
unregisterReceiver(receiver);
//结束服务,如果想让服务一直运行就注销此句
stopService(newIntent(this,GpsService.class));
super.onDestroy();
}
/**
*把经纬度换算成距离
*
*@paramlat1开始纬度
*@paramlon1开始经度
*@paramlat2结束纬度
*@paramlon2结束经度
*@return
*/
privatedoublegetDistance(doublelat1,doublelon1,doublelat2,doublelon2){
float[]results=newfloat[1];
Location.distanceBetween(lat1,lon1,lat2,lon2,results);
returnresults[0];
}
}
5、UtilTool–>工具类
packagecom.ljq.activity;
importjava.io.ByteArrayOutputStream;
importjava.io.IOException;
importjava.io.InputStream;
importjava.io.OutputStream;
importjava.io.UnsupportedEncodingException;
import.HttpURLConnection;
import.MalformedURLException;
import.ProtocolException;
import.URL;
importjava.util.ArrayList;
importjava.util.Calendar;
importjava.util.List;
importjava.util.Locale;
importorg.apache.http.client.ClientProtocolException;
importorg.json.JSONException;
importorg.json.JSONObject;
importandroid.content.Context;
importandroid.location.Location;
importandroid.location.LocationManager;
importandroid.telephony.NeighboringCellInfo;
importandroid.telephony.TelephonyManager;
importandroid.telephony.cdma.CdmaCellLocation;
importandroid.telephony.gsm.GsmCellLocation;
importandroid.util.Log;
importandroid.widget.Toast;
publicclassUtilTool{
publicstaticbooleanisGpsEnabled(LocationManagerlocationManager){
booleanisOpenGPS=locationManager.isProviderEnabled(android.location.LocationManager.GPS_PROVIDER);
booleanisOpenNetwork=locationManager.isProviderEnabled(android.location.LocationManager.NETWORK_PROVIDER);
if(isOpenGPS||isOpenNetwork){
returntrue;
}