IntentService STICKY und die Sensorüberwachung werden in Android gestoppt, wenn dies nicht der Fall sein sollte
-
14-11-2019 - |
Frage
In meiner onCreate-Anwendung überprüfe ich einige Bedingungen und starte dann eine Aktivität wie diese:
Intent startIntent = new Intent(getApplicationContext(), EnableLocationProviderActivity.class);
startIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getApplicationContext().startActivity(startIntent);
Von dieser Aktivität aus starte ich einen IntentService, der einige Listener für die Sensoren registriert. Er wird als STICKY gestartet, was bedeutet, dass er explizit gestoppt werden sollte.Dieser IntentService überwacht die Sensoren.
Mein Problem ist, dass, wenn ich zur ersten Aktivität zurückkomme, die Sensoren nicht mehr erkennen (ich habe ein Log.v in onSensorChanged eingefügt (die Daten werden zuerst angezeigt, und dann hört es auf).
Warum könnte es sein, dass es stoppt, wenn ich es nicht explizit gestoppt habe?Außerdem sehe ich manchmal, dass OnDestroy des IntentService aufgerufen wird, aber noch einmal: Wie kann es aufgerufen werden, wenn es STICKY ist und ich stopself() nicht aufgerufen und auf keine andere Weise gestoppt habe?
Danke!Guillermo.
BEARBEITEN
Dies ist der Code des IntentService (der die ganze Zeit laufen sollte, auch wenn das Mobiltelefon in den Ruhezustand wechselt oder die Home-Taste gedrückt wird (ich weiß über den Akku und alles andere Bescheid, der Benutzer wird darüber gewarnt und hat die Möglichkeit dazu um die Anwendung zu schließen, wenn er möchte.
Der Dienst wird von MainActivity aus wie folgt aufgerufen:
Intent startIntent = new Intent(GdpTesisApplication.getInstance().getApplicationContext(), SensingService.class);
startService(startIntent);
Und der Servicecode ist dieser:
public class SensingService extends IntentService implements SensorEventListener {
private float[] mAccelerationValues;
private SensorManager mSensorManager = null;
String sensorType = "";
public SensingService(String name) {
super(name);
setIntentRedelivery(true);
}
public SensingService() {
super("SensingService");
setIntentRedelivery(true);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.v(ApplicationName,"SensingService.onStartCommand");
super.onStartCommand(intent, flags, startId); // If this is not written then onHandleIntent is not called.
return START_STICKY;
}
@Override
public void onCreate() {
super.onCreate();
Log.v(ApplicationName, "SensingService.onCreate");
initialize();
}
private void initialize() {
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); // This must be in onCreate since it needs the Context to be created.
mAccelerationValues = new float[3];
Log.v(ApplicationName, "Opening Location Service from Sensing Service");
LocationService myLocation = new LocationService();
myLocation.getLocation(this, locationResult);
}
@Override
public void onDestroy() {
Log.v(ApplicationName, "SensingService.onDestroy");
super.onDestroy();
if (mSensorManager != null) {
mSensorManager.unregisterListener(this);
}
}
@Override
protected void onHandleIntent(Intent intent) {
Log.v(ApplicationName, "SensingService.onHandleIntent");
if (mSensorManager != null) {
registerListeners();
}
}
public LocationResult locationResult = new LocationResult() {
@Override
public void gotLocation(final Location location) {
if (location != null) {
Log.v(ApplicationName, "Location != null : (" + location.getLatitude() + "," + location.getLongitude() + ")");
} else {
Log.v(ApplicationName, "Location == null : (0,0)");
}
}
};
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
public void onSensorChanged(SensorEvent currentEvent) {
if (currentEvent.accuracy == SensorManager.SENSOR_STATUS_UNRELIABLE) {
return;
}
synchronized (this) {
float[] accelVals = null;
float totalForce = 0.0f;
int sensor = currentEvent.sensor.getType();
System.arraycopy(currentEvent.values, 0, mAccelerationValues, 0, 3); // We use System.arraycopy because of this:
switch (sensor) {
case Sensor.TYPE_ACCELEROMETER:
sensorType = "Accelerometer";
totalForce = SensorsHelpers.getTotalForceInGs(mAccelerationValues);
break;
case Sensor.TYPE_LINEAR_ACCELERATION:
sensorType = "LinearAcceleration";
totalForce = SensorsHelpers.getTotalForceInGs(mAccelerationValues) + 1;
break;
case Sensor.TYPE_GRAVITY:
totalForce = SensorsHelpers.getTotalForceInGs(mAccelerationValues);
sensorType = "Gravity";
break;
}
Log.v(ApplicationName,DateHelper.GetUTCdatetimeFromDate(new Date()) + " - from sensingService");
}
}
private void registerListeners() {
Log.v(ApplicationName, "Registering sensors listeners");
mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION), SensorManager.SENSOR_DELAY_UI);
mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY),SensorManager.SENSOR_DELAY_UI);
mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_UI);
}
}
UPDATE 2
Jetzt habe ich dies zur Methode onCreate hinzugefügt:
int NOTIFICATION_ID = 1;
Intent intent = new Intent(this, MainActivity.class);
PendingIntent pi = PendingIntent.getActivity(this, 1, intent, 0);
Notification notification = new Notification(R.drawable.ic_dialog_info, "Running in the Foregound", System.currentTimeMillis());
notification.setLatestEventInfo(this, "Title", "Text", pi);
notification.flags = notification.flags | Notification.FLAG_ONGOING_EVENT;
startForeground(NOTIFICATION_ID, notification);
um es als startForground zu starten, aber das Symbol wird in die Benachrichtigungsleiste eingefügt, dann wird onDestroy im Dienst aufgerufen und das Benachrichtigungssymbol verschwindet.
Ich bin jetzt verzweifelt!Bitte helfen Sie dabei!
Danke!Guillermo.
Lösung 2
Andere Tipps
Gemäß IntentService-Dokumentation:
Der Service wird nach Bedarf gestartet und kann jede Absicht mit einem Worker -Thread übernommen. und stoppt sich selbst, wenn ihm die Arbeit ausgeht
Laut derselben Dokumentation dürfen Sie auch nicht überschreiben onStartCommand()
Und onDestroy()
in deinem IntentService
, nehme ich an, weil es sein eigenes spezielles Verhalten implementiert, wie oben angegeben.Möglicherweise müssen Sie verlängern Service
anstatt IntentService
.