2014-06-11 7 views
6

Ich brauche den Benutzer über bestimmte Ereignisse aufmerksam zu machen durch: sollteWie der Vibrator von einem Dienst oder Empfänger auf unbestimmte Zeit halten

  • Vibration
  • Mitteilung

Die Vibration auf bleiben unbegrenzt, bis der Benutzer die Benachrichtigung bestätigt.

Das Problem ist, dass die Vibration stoppt, wenn das Gerät in den Ruhezustand wechselt. Ich habe folgende Fragen lauten:
Allow phone to vibrate when screen turns off
Continue vibration even after the screen goes to sleep mode in Android

Es an answer zu einem der oben genannten Fragen war zu sagen, dass es ohne Muster Vibrieren den Trick. Also habe ich versucht, die Version Vibrator.vibrate aufzurufen, die Millisekunden anstelle eines Musters mit einer großen Zahl akzeptiert, aber die Vibration stoppt trotzdem.

Andere Antworten schlagen vor, einen Empfänger auf der ACTION_SCREEN_OFF Aktion zu registrieren. Dies würde es mir ermöglichen, die Vibration fortzusetzen, wenn das Gerät nach dem Start des Alarms in den Ruhezustand geht, aber nicht funktioniert, wenn das Gerät bereits geschlafen hat.

Ich könnte jedoch die Sache funktionierte, wenn ich in der Lage wäre, den Bildschirm zuerst einzuschalten, dann registrieren Sie den Empfänger, um sich mit jedem Bildschirm-Aus-Ereignis zu befassen, das von dort weiter passieren könnte. Also habe ich versucht, eine vollständige Wecksperre zu erhalten, wenn das auslösende Ereignis empfangen wird, bevor Sound oder Vibration gestartet wird, aber es funktioniert nicht, obwohl ich die Flags FULL_WAKE_LOCK und ACQUIRE_CAUSES_WAKEUP verwende. Der Weckteil funktioniert, aber bald darauf geht das Gerät wieder in den Ruhezustand. Ich würde gerne glauben, dass das Flag FULL_WAKE_LOCK nicht funktioniert, weil es in API 17 veraltet ist, aber mein Gerät ist ein Samsung mit 4.1.2, das API 16 ist!

Der empfohlene Ansatz scheint jetzt WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON zu verwenden, aber dies sollte von einer Aktivität aufgerufen werden, und ich habe keine Bildschirm, bis der Benutzer in der Benachrichtigung klickt, und wenn dies passiert, sollte der Sound und die Vibration bereits haben wurde gestoppt.

So sieht es aus wie eine Sackgasse.

Was könnte ich noch versuchen?

UPDATE:
Ich hatte kein Glück, den Bildschirm immer mit Wake Locks zu halten, aber auf der anderen Seite erlauben sie mir, den Bildschirm einzuschalten, wenn auch nur für ein paar Sekunden. Ich muss den Bildschirm eigentlich nicht einschalten, also registriere ich den Empfänger auf der Intent.ACTION_SCREEN_OFF Aktion, und wenn der Bildschirm ausgeht, nimmt der Empfänger die Vibration wieder auf. Das hat im Samsung gut funktioniert, aber ich bin jetzt auf ein Huawei umgestiegen, um weiter zu testen und der Receiver funktioniert nicht.

UPDATE:
Hier ist der Stack-Trace der Ausnahme in dem Huawei-Gerät:

java.util.NoSuchElementException: Death link does not exist 
    at android.os.BinderProxy.unlinkToDeath(Native Method) 
    at com.android.server.VibratorService.unlinkVibration(VibratorService.java:294) 
    at com.android.server.VibratorService.removeVibrationLocked(VibratorService.java:284) 
    at com.android.server.VibratorService.cancelVibrate(VibratorService.java:213) 
    at android.os.IVibratorService$Stub.onTransact(IVibratorService.java:83) 
    at android.os.Binder.execTransact(Binder.java:338) 
    at dalvik.system.NativeStart.run(Native Method) 

Antwort

1

Nach ein paar Tests habe ich es endlich geschafft, es zum Laufen zu bringen.

Die Vibrator Klasse Hass zwei Methoden:

  • vibrate (long[] pattern, int repeat)
  • vibrate (long milliseconds)

Die first one ist der einzige Weg, auf unbestimmte Zeit mit der API der schwing (vorbei 0 als zweites Argument). Aber das hat sich bei einigen Geräten (Huawei) bewährt, wie ich in der Frage geschrieben habe. Ich spreche nicht über die Vibration, die vom Betriebssystem gestoppt wird, wenn das Gerät in den Schlaf geht, dies wurde mit einem Empfänger und einem Weckschloss wie in der Frage beschrieben behandelt. Ich spreche über Ausnahmen, die durch eine fehlerhafte Implementierung verursacht wurden (die Vibrator-Klasse ist abstrakt).

Die second variant dieser Methode akzeptiert kein Muster und erlaubt keine unbestimmte Schwingung, aber wir können dies betrügen, indem wir eine sehr große Anzahl von Millisekunden als Parameter übergeben. Dies funktioniert gut in einigen Geräten (Huawei) als the answer I cited in the question richtig angezeigt, aber funktioniert nicht in anderen (Samsung), wo die Implementierung einen Standard-Max-Wert hat, der stattdessen verwendet wird, wenn der als Parameter übergebene Wert überschreitet. Dieser Maximalwert ist tatsächlich weniger als eine Minute und das bedeutet, dass wir uns nicht auf diesen Ansatz verlassen können.

Also ging ich alle auf diesem und eine Service erstellt, wo ich so manuell auf unbestimmte Zeit vibrieren:

while(vibrationActive){ 
     Vibrator.vibrate(1000); 
     Thread.sleep(1000); 
    } 

Der Empfänger Trick zu erkennen, wenn der Bildschirm kein wird erlischt mehr benötigt. Natürlich unterbricht das Betriebssystem den Vibrator, wenn dies passiert, aber die nächste Iteration der Schleife wird die Vibration wieder aufnehmen. Mit diesem Ansatz ist es möglich, auch eine Art Muster zu erstellen, wenn die Ruhezeit größer als die Vibrationszeit ist, aber dieses Muster wird auch an irgendeinem Punkt unterbrochen, wenn der Bildschirm ausgeht.

Ein spezieller Service, um den Vibrator zuverlässig ein- und auszuschalten. Können Sie das glauben? Ungefähr 150 Codezeilen (ohne die Unit-Tests) für etwas, was mit ein paar Zeilen möglich gewesen wäre.

1

Beabsichtigen Sie, das Gerät zu lassen schlafen gehen oder nicht? Sie können einen Wakelock erwerben, der den Bildschirm aktiviert.

PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); 
    WakeLock wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.ON_AFTER_RELEASE, "myTAG"); 
    wl.acquire(LOCK_SCREEN_TIME_MINUTES * 60 * 1000); 

Das funktioniert nicht für Sie? Danach können Sie die Benachrichtigung anzeigen, aber ich bin mir nicht sicher über den Effekt, wird es die Vibrationen halten. Oben arbeitet man auf GalaxyTab 2 mit Android 4.2.2 und HTC Hero mit Android 2.3.4.

+0

Das sind eigentlich meine Flags, außer dem 'ON_AFTER_RELEASE', das ich nicht brauche. Und was passiert in diesem Samsung ist, dass es tatsächlich anschaltet, aber nach 1 oder 2 Sekunden geht es wieder ohne dass ich das Schloss freigegeben habe. Das ist jetzt egal, da ich den Bildschirm nicht ständig brauche. Ich werde eine Antwort schreiben und erklären, was ich getan habe. –

+0

ok, ich freue mich auf deine Antwort, ich bin gespannt darauf. – Nexowski

+0

habe es gerade gepostet. –