当应用程序在后台运行时无法找到位置更新
Posted
技术标签:
【中文标题】当应用程序在后台运行时无法找到位置更新【英文标题】:Unable to find location updates when an application is running in the background 【发布时间】:2012-04-20 16:06:58 【问题描述】:我正在尝试创建一个应用程序,我想在其中连续运行 android 应用程序。
我创建了服务类以在后台运行应用程序以进行位置更新。 该服务不会连续运行,但会在一段时间后停止。下面是启动服务的 Boot 接收器类。
我已经把 Service 和 Boot Receiver 两个类都放到了。
我做错了什么还是错过了什么?
/********************Boot receiver********************/
import java.util.Calendar;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.Toast;
public class BootReceiver extends BroadcastReceiver
@Override
public void onReceive(Context context, Intent intent)
// TODO Auto-generated method stub
Log.i("IntentReceiver", "Got intent " + intent.getAction() + " / data: " + intent.getDataString());
try
Intent i = new Intent(context,MyService.class);
PendingIntent pendingIntent = PendingIntent.getService(context, 0, i, 0);
AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.SECOND, 20);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 1000, pendingIntent);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startService(i);
catch (Exception e)
e.printStackTrace();
/**********************Myservice*********************/
import java.util.Date;
import com.safecell.dataaccess.InteruptionRepository;
import com.safecell.dataaccess.TempTripJourneyWayPointsRepository;
import com.safecell.model.SCProfile;
import com.safecell.model.SCWayPoint;
import com.safecell.receiver.LockReceiver;
import com.safecell.utilities.DateUtils;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningServiceInfo;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.media.AudioManager;
public class MyService extends Service
private static LocationManager mlocManager;
private static final String TAG = "MyService";
public static double x=0.0 ,y=0.0,last_x=0.0,last_y=0.0;
SharedPreferences sharedPreferences;
public static int j=0;
public static TrackingScreenActivity trackingScreenActivity = null;
public static TrackingService trackingService;
static TempTripJourneyWayPointsRepository tempTripJourneyWayPointsRepository;
double speed = 0.0;
private float lastDistanceInMiles = 0;
@Override
public IBinder onBind(Intent intent)
return null;
@Override
public void onCreate()
Toast.makeText(this, "My Service Created", Toast.LENGTH_LONG).show();
Log.d(TAG, "onCreate");
@Override
public void onDestroy()
Toast.makeText(this, "My Service Stopped", Toast.LENGTH_LONG).show();
Log.d(TAG, "onDestroy");
@Override
public void onStart(Intent intent, int startid)
//Toast.makeText(this, "start My Service Started", Toast.LENGTH_LONG).show();
Log.d(TAG, "onStart");
if(SplashScreenActivity.act_flag)
else
Intent myStarterIntent = new Intent(getApplicationContext(), SplashScreenActivity.class);
myStarterIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getApplicationContext().startActivity(myStarterIntent);
sharedPreferences = getSharedPreferences("TRIP", MODE_WORLD_READABLE);
mlocManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
LocationListener mlocListener = new MyLocationListener();
mlocManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, 0, 0, mlocListener);
/***********************To insert a record in an nsqlite table**********************/
private void insertWaypoint(Location location)
// InteruptionRepository
tempTripJourneyWayPointsRepository= new TempTripJourneyWayPointsRepository(
getApplicationContext());
double distanceInMiles = tempTripJourneyWayPointsRepository.getDistanceDifference(location);
//Toast.makeText( getApplicationContext(),
// "didf=f"+distanceInMiles,
// Toast.LENGTH_SHORT).show();
long currentTime = new Date().getTime();
double timeDifference = tempTripJourneyWayPointsRepository.getTimeDiffernce(currentTime);
double avarageSpeed = tempTripJourneyWayPointsRepository.getAvarageEstimatedSpeedForAutoTripStart();
SharedPreferences sharedPreferences = getSharedPreferences("TRIP", MODE_WORLD_READABLE);
boolean isTripStarted = sharedPreferences.getBoolean("isTripStarted", false);
if (timeDifference != 0 && distanceInMiles!=0)
speed = distanceInMiles / timeDifference;
Toast.makeText( getApplicationContext(), "didf=f"+speed, Toast.LENGTH_SHORT).show();
boolean background = true;
if (isTripStarted)
AudioManager aManager = (AudioManager) getSystemService(AUDIO_SERVICE);
aManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
SCWayPoint wayPoint =
new SCWayPoint(0, 0,
DateUtils.getTimeStamp(currentTime),
location.getLatitude(), location.getLongitude(), speed,
background);
tempTripJourneyWayPointsRepository.intsertWaypoint(wayPoint);
// if trip started
// trackingScreenActivity.dismProgressDialog();
/* Class My Location Listener */
public class MyLocationListener implements LocationListener
@Override
public void onLocationChanged(Location loc)
Log.d(TAG, "onlocationchnage");
x=loc.getLatitude();
y=loc.getLongitude();
int d3= calcDistance(last_x,last_y,x,y);
double speed;
if (d3>20)
speed = d3/20;
else
speed=0.0;
j++;
String Text ="My current location is: " +
"Latitud1 = " +x +
"Longitud1 = " +y+
"Latitud2 = " + last_x +
"Longitud2 = " + last_y+
"j=" +j+
"distance="+d3+" Speed : "+speed;
Toast.makeText( getApplicationContext(), Text, Toast.LENGTH_SHORT).show();
if(speed>10)
TempTripJourneyWayPointsRepository tempTripJourneyWayPointsRepository =
new TempTripJourneyWayPointsRepository(getApplicationContext());
tempTripJourneyWayPointsRepository.deleteTrip();
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putBoolean("isTripPaused", false);
editor.putBoolean("isTripStarted", true);
editor.commit();
insertWaypoint(loc);
if(speed < 10.0)
//Toast.makeText(getApplicationContext(), "hoooo service"+speed, Toast.LENGTH_LONG).show();
if(isMyServiceRunning())
//trackingService.saveTripAsyncTask(getApplicationContext());
// Toast.makeText(getApplicationContext(), "hiiiiiiiiiiiiiiii Service", Toast.LENGTH_LONG).show();
//trackingScreenActivity.btnStop.performClick();
//trackingScreenActivity.stoptripinservice();
// AddTripActivity.addTripActivity=
//SharedPreferences.Editor editor = sharedPreferences.edit();
//editor.putBoolean("isTripSaved", true);
//editor.commit();
last_x=loc.getLatitude();
last_y=loc.getLongitude();
public void editGenereateTripUniqueID(String uniqueId)
SharedPreferences.Editor editorUniqueID =
TrackingService.context.getSharedPreferences("TripJouneryUID", MODE_WORLD_WRITEABLE).edit();
editorUniqueID.putString("UniqueIdForTrip", uniqueId);
editorUniqueID.commit();
//Log.v("Safecell : --UniqueIdForTrip", "ID = "+uniqueId);
private Double distance(double lat1, double lon1, double lat2, double lon2)
/* double theta = lon1 - lon2;
double dist = Math.sin(deg2rad(lat1)) * Math.sin(deg2rad(lat2)) +
Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * Math.cos(deg2rad(theta));
dist = Math.acos(dist);
dist = rad2deg(dist);
dist = dist * 60;
dist = dist * 1852;*/
double dlon = lon2 - lon1;
double dlat = lat2 - lat1;
double a = Math.pow((Math.sin(dlat/2)),2) +
Math.cos(lat1) * Math.cos(lat2) * Math.pow((Math.sin(dlon/2)),2);
double c = 2 * Math.atan2( Math.sqrt(a), Math.sqrt(1-a) );
double d = 6373 * c;
return (d);
private boolean isMyServiceRunning()
ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE))
if ("com.safecell.TrackingService".equals(service.service.getClassName()))
return true;
return false;
public int calcDistance(double latA, double longA, double latB, double longB)
double theDistance = (Math.sin(Math.toRadians(latA)) *
Math.sin(Math.toRadians(latB)) +
Math.cos(Math.toRadians(latA)) *
Math.cos(Math.toRadians(latB)) *
Math.cos(Math.toRadians(longA - longB)));
return new Double((Math.toDegrees(Math.acos(theDistance))) * 69.09*1.6093).intValue();
private double deg2rad(double deg)
return (deg * Math.PI / 180.0);
private double rad2deg(double rad)
return (rad * 180.0 / Math.PI);
@Override
public void onProviderDisabled(String provider)
// Toast.makeText( getApplicationContext(), "Gps Disabled", Toast.LENGTH_SHORT ).show();
@Override
public void onProviderEnabled(String provider)
// Toast.makeText( getApplicationContext(), "Gps Enabled", Toast.LENGTH_SHORT).show();
@Override
public void onStatusChanged(String provider, int status, Bundle extras)
/* End of Class MyLocationListener */
【问题讨论】:
【参考方案1】:我没有信心,但我有一个想法。
您应该设置 TIMEZONE_CHANGED 的广播。更改日期和时间时,PF 可能会重置警报管理器。并且某些 Android 设备默认日期和时间设置是自动的!
您应该在 Service#onCreate() 上从低内存杀手编写重启操作代码。重新启动服务时,也许 PF 会调用 Service#onCreate()
。 PF 注册终止了你的服务并重新启动了你的服务。
Service#onStart()
重新检查您关于NullPointerException
的代码。 PF 可能会将 null 设置为 onStart 意图参数。
您可以考虑设置PowerManager#WakeLock
。 PF 休眠时服务无法运行。
PS:您可以查看以下有关 PowerManager 和前台服务的 Android 错误。
WakeLock Timeout causes WakeLock under-locked on Timeout Notification won't be created as ongoing when starting foreground service【讨论】:
如果你想创建低内存杀手的情况并重置AlarmManager。你尝试关注 [重置 AlarmManager 测试]。 1:断网。 2:关闭数据和时间的自动。 3:更改日期。但具体的依赖设备。 [Low Memory Kill Test] 我推荐使用我的应用程序。这个应用程序很容易创建低内存状态。 github.com/kyorohiro/KyoroHelloAndroidKyoroStress.apk 或play.google.com/store/apps/…以上是关于当应用程序在后台运行时无法找到位置更新的主要内容,如果未能解决你的问题,请参考以下文章