我有Android应用程序,我想在用户单击开始按钮时计算每两分钟的距离。所以我的应用程序中有Service类,在该类中我有googleapiclient。
所以我每两分钟就有一个位置我在共享偏好中添加了这个距离,但是移动进入睡眠模式意味着,当用户点击结束按钮时距离不计算。
我认为服务会停止。请帮我解决问题。 移动进入睡眠模式时我必须做什么,如果我在活动页面中计算距离意味着当应用程序处于背景距离时不会计算,这就是为什么我在服务中添加距离。
代码:
public class MyLocationService2 extends Service implements GoogleApiClient.ConnectionCallbacks,GoogleApiClient.OnConnectionFailedListener, LocationListener {
LocationManager locationManager ;
SharedPreferences sharedPreferences,startdistance_preference;
SharedPreferences.Editor editor;
Timer timer;
String networkinformation;
MyLocationService.MyTimerTask myTask;
String gs_var_userid,gs_var_usetoken;
private GoogleApiClient mGoogleApiClient = null;
Double mlastlocationlat,mlastlocationlong,mcurrentlocationlat,mcurrentlocationlong;
private static final LocationRequest REQUEST = LocationRequest.create()
.setInterval(10000)
.setFastestInterval(10000)
.setSmallestDisplacement(0)
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
public static boolean isGPSEnabled = false;
public static boolean isNetworkEnabled = false;
String strlevel;
SimpleDateFormat simpledateformat;
String Date;
int deviceStatus;
String currentBatteryStatus="Battery Info";
private final int UPDATE_INTERVAL = 10000; // 5 sec
private final int FASTEST_INTERVAL = 10000; // 1 sec
private final int DISPLACEMENT = 0; // 10 meters
LocationRequest mLocationRequest;
public void createLocationRequest() {
mLocationRequest = LocationRequest.create();
mLocationRequest.setInterval(UPDATE_INTERVAL);
mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setSmallestDisplacement(DISPLACEMENT);
}
String provider;
double f_TotDist ;
//to check gps is enabled or not
@Override
public void onCreate() {
super.onCreate();
Log.i("FG","oncreate");
locationManager = (LocationManager) getApplicationContext().getSystemService(LOCATION_SERVICE);
isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
mGoogleApiClient = new GoogleApiClient.Builder(getApplicationContext())
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mGoogleApiClient.connect();
createLocationRequest();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
@Override
public void onLowMemory() {
super.onLowMemory();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i("DF","ondestroy");
// mGoogleApiClient.disconnect();
// LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
private synchronized void buildGoogleApiClient() {
try {
mGoogleApiClient = new GoogleApiClient.Builder(getApplicationContext())
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mGoogleApiClient.connect();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onConnected(@Nullable Bundle bundle) {
try {
Log.i("FG","----onConnected----service1");
if (ActivityCompat.checkSelfPermission(getApplicationContext(), android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getApplicationContext(), android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
if (mGoogleApiClient != null) {
mGoogleApiClient.connect();
mGoogleApiClient.connect();
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient,
REQUEST,
this); // LocationListener
}
else
{
buildGoogleApiClient();
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient,
REQUEST,
this); // LocationListener
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onConnectionSuspended(int i) {
}
// to get current latitude and longitude
// storing the updated latitde and longitude when user moving and reach destination
@Override
public void onLocationChanged(Location location) {
try {
Log.i("MS","service class********"+location);
sharedPreferences = getSharedPreferences("myprefer", MODE_PRIVATE);
editor = sharedPreferences.edit();
gs_var_userid=Prefs.getuserid(getApplicationContext());
gs_var_usetoken=Prefs.getusertokene(getApplicationContext());
editor.putString("dest_Lat", String.valueOf(location.getLatitude()));
editor.putString("dest_Long", String.valueOf(location.getLongitude()));
editor.putString("Lat", String.valueOf(location.getLatitude()));
editor.putString("Long", String.valueOf(location.getLongitude()));
startdistance_preference = getSharedPreferences("startLessonPref",
Context.MODE_PRIVATE);
if(mlastlocationlat==null && mlastlocationlong==null && mcurrentlocationlat==null && mcurrentlocationlong==null)
{
mlastlocationlat=location.getLatitude();
mlastlocationlong=location.getLongitude();
mcurrentlocationlat=location.getLatitude();
mcurrentlocationlong=location.getLongitude();
}
else
{
mlastlocationlat=mcurrentlocationlat;
mlastlocationlong=mcurrentlocationlong;
mcurrentlocationlat=location.getLatitude();
mcurrentlocationlong=location.getLongitude();
}
editor.commit();
Float dist = distanceCal(mlastlocationlat, mlastlocationlong,mcurrentlocationlat, mcurrentlocationlong);
} catch (Exception e) {
e.printStackTrace();
}
}
private float distanceCal(double lat1, double lon1, double lat2, double lon2) {
Location loc1 = new Location("");
loc1.setLatitude(lat1);
loc1.setLongitude(lon1);
Location loc2 = new Location("");
loc2.setLatitude(lat2);
loc2.setLongitude(lon2);
float distanceInMeters = loc1.distanceTo(loc2);
Log.e("RS--first--","-distanceInMeters-" +distanceInMeters);
Log.e("RS---#####-1-" + lat1, "--" + lon1);
Log.e("RS---#####-2-" + lat2, "--" + lon2);
startdistance_preference = getSharedPreferences("startLessonPref",
Context.MODE_PRIVATE);
f_TotDist = startdistance_preference.getFloat("str_TotalDist", 0);
Log.e("RS","-f_TotDist-first-" +f_TotDist);
// startLesson_preference = getSharedPreferences("startLessonPref", Context.MODE_PRIVATE);
f_TotDist+=(distanceInMeters);
Log.e("RS","-f_TotDist--if-" +f_TotDist);
SharedPreferences.Editor editor1 = startdistance_preference.edit();
editor1.putFloat("str_TotalDist", (float) f_TotDist);
editor1.commit();
return distanceInMeters;
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
}
在活动中,用户点击结束时我离服务很远,但如果进入睡眠模式意味着我没有距离,即使我在活动页面中使用sqlite打印距离但是当它进入睡眠状态时模式服务停止我想。请帮助我
答案 0 :(得分:0)
它符合OS设计。从Android O
开始,当应用程序位于前台时,它可以自由地创建和运行后台服务。
当一个应用程序进入后台时,它有一个几分钟的窗口(根据我的观察,大约1 - 2分钟,甚至更少的其他一些deivces),其中仍然允许创建和使用服务。系统会停止应用程序的后台服务,就像应用程序调用了服务一样。 Service.stopSelf()
方法。
您应该避免连续运行服务,因为它会影响电池寿命。如果您仍想继续使用最佳替代方案,请使用ForegroundService
。但是,如果系统认为您的服务消耗太多处理,那么在打盹模式下,该服务也不会起作用。
您可以按照此SO说明如何使用ForegroundService。
有关位置请求,请查看此official document。从Android O开始,您无法频繁请求位置更新(每两分钟一次)。
答案 1 :(得分:0)
从Android Oreo(API 26)背景和后台位置检索中运行服务有严重限制以保留电池,应用程序现在可以在一小时内获得位置更新(当应用程序没有限制时在前景中)
此处有更多详情:
要克服基于位置的应用中的限制,请创建一个BroadCastReceiver
,它将获得意图并具有处理位置数据后处理应用特定代码的逻辑。
在后台触发位置数据时,使用pendingIntent检索Intent,如下所示:
Intent intent = new Intent(this, LocationUpdatesBroadcastReceiver.class);
intent.setAction(LocationUpdatesBroadcastReceiver.ACTION_PROCESS_UPDATES);
return PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
google提供的分步指南,用于处理oreo的位置:https://codelabs.developers.google.com/codelabs/background-location-updates-android-o/#0
(您可能需要从第5步更详细地了解如何处理oreo)