IntentService STICKY und die Sensorüberwachung werden in Android gestoppt, wenn dies nicht der Fall sein sollte

StackOverflow https://stackoverflow.com/questions/9501163

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.

War es hilfreich?

Lösung 2

0Wenn niemand mir zeigt, ist es ein Problem mit meinem Code, für mich wird es ein Fehler sein.Danke!

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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top