Android 自定义GPS 位置上报工具,结合Rxjava+
import java.util.List;
import java.util.Timer;
import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.Settings;
import android.support.v4.app.ActivityCompat;
import android.util.Log;
import android.widget.Toast;
import com.baidu.mapapi.model.LatLng;
import com.tsgz.aerors.lztlcrew.android.ClientCoreSDK;
import com.tsgz.aerors.lztlcrew.app.Api;
import com.tsgz.aerors.lztlcrew.bean.LocationEntity;
import com.tsgz.aerors.lztlcrew.receiver.UpLocationServiceGenerator;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.schedulers.Schedulers;
/**
* 自动位置上报管理类
*/
public class LocationSubmitManager {
private static final StringTAG ="LocationSubmitManager";
private static int timeUnit =60;// 分钟转为秒
private Contextcontext;
private SharePreferenceUtilsharePreferenceUtil;
private LocationManagerlm;
private int secInterval;// 秒时间间隔
private StringbestProvider;
private HandlerpositionHandler =null;
private static Timertimer =null;
private static boolean isTransmit =false;// 定位是否已发送
private static boolean isValid =false;// 定位是否有效
private LocationsendLocation;//发送的地理位置
//private List testLocationList;
//登录账号的类型,计划施工1,非计划施工0,机车2
private int type;
private double preLocationLat,preLocationLong;
private static SubscriptionmSubscription;
public LocationSubmitManager(Context context) {
this.context = context;
preLocationLat =0;
preLocationLong =0;
isTransmit =false;
isValid =false;
sharePreferenceUtil.getInstance(context);
type = SharePreferenceUtil.getInstance(context).getUserType();
lm = (LocationManager)this.context.getSystemService(Context.LOCATION_SERVICE);
//发送时间间隔,若是按照分钟来算的话,*60;例子:一分钟发送一次
//测试修改30s发送一次位置;60--》30
secInterval = SharePreferenceUtil.getInstance(context).getAutoSubmitTime() *5;
}
/*启动位置上报*/
public void startLocationSubmit() {
// 判断GPS是否正常启动
if (!lm.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
Toast.makeText(context,"请开启GPS定位...", Toast.LENGTH_LONG)
.show();
// 返回开启GPS导航设置界面
Intent intent =new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
context.startActivity(intent);
return;
}
System.out.println("时间间隔为:" +secInterval +"s");
// 绑定位置监听
// bestProvider = lm.getBestProvider(getCriteria(), true);
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER,secInterval *1000,0,
new MyLocationListener());
positionHandler =new PositionHandler(context);
if (timer !=null) {
timer.cancel();
}
timer =new Timer();
timer.schedule(new PositionIntervalTimerTask(positionHandler),0,
secInterval *1000);
Toast.makeText(context,"已开启自动位置上报", Toast.LENGTH_SHORT).show();
}
/*
停止位置上报*/
public static void stopLocationSubmit() {
if (timer !=null) {
// 结束定时器任务
timer.cancel();
timer =null;
}
isTransmit =false;
isValid =false;
Log.e("LocationSubmitManager","stopLocationSubmit");
}
/*获取定位条件Criteria*/
private Criteria getCriteria() {
Criteria criteria =new Criteria();
// 设置定位精确度 Criteria.ACCURACY_COARSE比较粗略,Criteria.ACCURACY_FINE比较精细
criteria.setAccuracy(Criteria.ACCURACY_FINE);
// 设置是否要求速度
criteria.setSpeedRequired(true);
// 设置是否允许运营商收费
criteria.setCostAllowed(false);
// 设置是否需要方位信息
criteria.setBearingRequired(true);
// 设置是否需要海拔信息
criteria.setAltitudeRequired(true);
// 设置对电源的需求
criteria.setPowerRequirement(Criteria.POWER_LOW);
return criteria;
}
/*位置监听*/
public class MyLocationListenerimplements LocationListener {
public MyLocationListener() {
super();
}
@Override
public void onLocationChanged(Location location) {
// 定位有效
isValid =true;
}
@Override
public void onProviderDisabled(String provider) {
// 定位已关闭,定位无效
isValid =false;
Toast.makeText(context,"已关闭定位", Toast.LENGTH_SHORT).show();
}
@Override
public void onProviderEnabled(String provider) {
Toast.makeText(context,"已开启定位", Toast.LENGTH_SHORT).show();
}
@Override
public void onStatusChanged(String provider,int status, Bundle extras) {
switch (status) {
// GPS状态为可见时
case LocationProvider.AVAILABLE:
Log.i(TAG,"当前GPS状态为可见状态");
// 定位有效
isValid =true;
break;
// GPS状态为服务区外时
case LocationProvider.OUT_OF_SERVICE:
Log.i(TAG,"当前GPS状态为服务区外状态");
// 定位无效
isValid =false;
break;
// GPS状态为暂停服务时
case LocationProvider.TEMPORARILY_UNAVAILABLE:
Log.i(TAG,"当前GPS状态为暂停服务状态");
// 定位无效
isValid =false;
break;
}
}
}
/*自动位置上报处理*/
class PositionHandlerextends Handler {
private Contextcontext;
public PositionHandler(Context context) {
super();
this.context = context;
}
@Override
public void handleMessage(Message msg) {
// Log.i(TAG, "handleMessage");
// 自动位置上报是否开启
if (!SharePreferenceUtil.getInstance(context).getIsAutoSubmit()) {
// 停止位置上报
stopLocationSubmit();
return;
}
// 获取最近一次位置
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
Location location =lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
// location为空,说明定位已经关闭
//源程序,未修改之前的程序,自动定位进行位置上报
if (location ==null) {
Log.e("LocationSubmitManager","location == null");
// 停止位置上报
Toast.makeText(context,"定位失败,无法上报位置!", Toast.LENGTH_LONG).show();
return;
}
/* if (location == null) {
Log.e("LocationSubmitManager", "location == null");
locationPosition = SharePreferenceUtil.getInstance(context).getAutoLocationPos();
if (locationPosition >= testLocationList.size()) {
//如果记录的上报位置的数据位置超出了模拟数据的大小,则记录位置清零。locationPosition = 0;
}
location = testLocationList.get(locationPosition);
locationPosition++;
//设置是否自定义上报位置,进行开关设置
SharePreferenceUtil.getInstance(context).setAutolocationpos(locationPosition);
}*/
if (isTransmit) {
sendLocation =null;
isTransmit =false;
}
// 发送
sendLocation = location;
Log.e("当前的位置",sendLocation.getSpeed() +"");
//判断当前定位点是否和前一个定位点相同,若相同则不上传当前的位置;若不同则上传当前位置。
/*if (preLocationLat == sendLocation.getLatitude() && preLocationLong == sendLocation.getLongitude()) {*/
/* if (sendLocation.getSpeed() < 1.0f) {
ToastUtil.show(context, "位置未发生变化");
} else {*/
sendLocation(sendLocation);
/* }*/
isTransmit =true;
}
}
private void sendLocation(final Location location) {
if (location ==null) {
return;
}
if (type ==10) {
ToastUtil.show(context,"上报位置失败:无法获取该用户类型,请重新登陆或联系管理员");
return;
}else if (SharePreferenceUtil.getInstance(context).getIsAutoSubmit()) {
LatLng latLng = GPS2BaiDuUtil.convert(new LatLng(location.getLatitude(), location.getLongitude()));
SharePreferenceUtil.getInstance(context).setCurrentLocation(latLng.latitude +"," + latLng.longitude);
ToastUtil.show(context, latLng.toString());
mSubscription = UpLocationServiceGenerator.createService(Api.reLocation.class)
.location(latLng.latitude, latLng.longitude, ClientCoreSDK.getInstance().getCurrentLoginUserId(),type,location.getSpeed(),System.currentTimeMillis())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1>() {
@Override
public void call(List locationEntities) {
for (LocationEntity locationEntity : locationEntities) {
preLocationLat =location.getLatitude();
preLocationLong =location.getLongitude();
}
}
},new Action1() {
@Override
public void call(Throwable throwable) {
try {
Log.e("发送位置失败", throwable.getMessage());
}catch (Exception e) {
e.printStackTrace();
Log.e("发送位置失败","服务器异常");
}
}
});
/* String contentStr = "{" + "\"lon\":" + location.getLongitude() + ","
+ "\"speed\":" + location.getSpeed() + ","
+ "\"bearing\":" + location.getBearing() + ","
+ "\"time\":" + System.currentTimeMillis() + ","
+ "\"type\":" + type + ","
+ "\"userid\":" + ClientCoreSDK.getInstance().getCurrentLoginUserId() + ","
+ "\"lat\":" + location.getLatitude() + "}";
Log.e("上报内容", contentStr);
mSubscription = UpLocationServiceGenerator.createService(Api.upLocation.class)
.location(contentStr)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1>() {
@Override
public void call(List locationEntities) {
for (LocationEntity locationEntity : locationEntities) {
preLocationLat = location.getLatitude();
preLocationLong = location.getLongitude();
}
}
}, new Action1() {
@Override
public void call(Throwable throwable) {
Log.e("发送位置失败", "发送失败");
}
});
*/
}
}
}