App-Design

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Hallo

    Ich brauch wieder mal einen Rat von euch Profis, nein, sogar gleich deren zwei. Ich will (immer noch) eine App schreiben, die alle 3 Minuten meine wichtigsten Systemeinstellungen kontrolliert (z.B. ob "Mobile Daten" nicht irrtümlich eingeschaltet blieb, was unterwegs innert Kürze unbemerkt mein Prepaid-Konto leeren würde). Das gelang mir soweit auch.

    1) Nun möchte ich aber auch noch, dass meine Kontrolle sofort ausgeführt wird, wenn ich die App wieder in den Vordergrund bringe (zu einem Zeitpunkt MITTEN in den 3-minütigen Intervallen). Mache ich das mit "onRestart" auf folgende Weise,

    Quellcode

    1. public class MainActivity extends Activity {
    2. ...
    3. @Override
    4. protected void onRestart() {
    5. super.onRestart();
    6. UpdateNotification updateNotificationRestartRun = new UpdateNotification();
    7. updateNotificationRestartRun.run();
    8. }
    9. public class UpdateNotification extends TimerTask {
    10. ...
    11. public void run() {
    12. ...
    13. }
    14. }
    15. }
    Alles anzeigen
    so wird zwar das Unterprogramm "run" ausgeführt, aber mit eigenen Initialdaten und nicht diejenigen, welche die 3-Minuten-periodische Prozedur aktuell hat. Meine erste Idee war eine statische Methode "run". Aber Unterklassen dürfen keine statische Methoden haben. Ich denke, es gibt eine ganz einfache Lösung, aber als ziemlich blutiger Anfänger fehlt mir hierfür die Erfahrung ...

    2) Wenn ich alle zuletzt verwendeten Apps mittels "Alle schliessen" beende, endet auch meine Kontroll-App, und ich bin ohne Schutz gegen meine Vergesslichkeit. Fieserweise bleibt dann auch das Notification-Icon meiner App bestehen und wiegt mich im Glauben, meine App laufe noch. Ich hab schon versucht, das Unterprogramm "run" als Hintergrunddienst (gestarteter Dienst, IntentService) zu schreiben, aber auch so wird der Dienst beendet, wenn ich die App schliesse. Meine App sollte also unsichtbar und unschliessbar sein (und bei Neustart des Handys auch aufstarten). Dass dies möchlich ist, beweist mir die App "Waterbot" aus dem PlayStore, die genau diese Eigenschaften hat und mich z.B. alle 5 Tage ans Blumengiessen erinnert. Nur, wie erreiche ich dieses Ziel?

    Herzlichen Dank für alle Tipps!
  • Hallo zu Punkt Eins würde sich onResume als Methode besser eignen. Die wird immer wenn die app im Hindergrund war auf gerufen. Schaue dier den lifestyle eine activity an. Bei OnRestart muss die app vorher getoppt sein.
    Die Kenntnisse des Lifecycle ist für dich hier besonders wichtig.
    Ein Feedback auf Tipps ist auch schön. :P

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von jogimuc ()

  • Ein intent Service ist immer an eine activity gekoppelt.
    Seit android 6 7 8 ist es nicht mehr so einfach einen Hindergrund Dienst am Laufen zu halten.
    Um ein bestimmten zimlich genauen Termin zu setzen würde sich der alarmmanager eignen der auch im hinderund arbeitet. Dieser startet dann einen Service oder resiever.
    Bei einen sich selbst wiederholenden alarmmanager musst du auf passen der wird auch manchmal unter 7 8 gekillt..

    Zum start deiner app nach dem reboot oder auch beim Bildschirm on brauchst du einen resiver der im Manifest erstellt ist. Die Action müsste ich jetzt auch erst nach schauen.
    Bildschirm on off geht nur mit einen zu Laufzeit Gesetzen resiver. Aber es gab noch eine die dir mitgeteilt ob der User am Handy ist die auch bei 8 noch im Manifest ist. Weis ich jetzt nicht aus dem Kopf.
    Ein Feedback auf Tipps ist auch schön. :P

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von jogimuc ()

  • Hallo jogimuc

    Danke für deine Antworten. Zu deiner Entgegnung auf mein erstes Problem: Genau das hab ich gemacht, mich über den Lifecycle informiert, nämlich hier (runterscrollen bis zur Grafik). Da siehst du, warum ich "onRestart" nehme: Bei deinem Vorschlag "onResume" würde die Methode "run" auch schon unnötigerweise beim Aufstart der App ausgeführt, wenn der Timer sowieso anspringt und "run" ausführt... Aber das ist eigentlich nicht das wesentliche Problem. Ich kann "run" zu selbst gewählten Zeitpunkten nur ausführen, indem ich von dieser Methode eine eigene Instanz erzeuge, die dann aber keinen Zugriff auf die aktuellen Daten der vom Timer erzeugten regelmässigen Durchführungen von "run" haben. Gibt es sowas wie globale Variablen, auf die meine Instanz und die Instanz vom Timer zugreifen können? Oder wie können diese beiden Instanzen von "run" gegenseitig Daten austauschen? Ist das überhaupt möglich?

    Die Antwort auf Frage 2 hilft mir (wie ich es sehe) nicht wirklich weiter: Auch einen Alarmmanager müsste ich in meiner App mit einem Timer alle 3 Minuten setzen. Kille ich meine App, ist auch der Alarmmanager ohne Auftrag... Aber einen "ewigen" und unsichtbaren Dienst ist möglich - wie geschrieben funktioniert die App "Waterbot" auf meinem Android 8.0 genau so und ohne Probleme.

    Wer noch ergänzende Bemerkungen zu meinen Fragen hat, ist hoch willkommen!
  • Also ein Alarmmanager läuft immer ist ein System Dienst.
    Wo du den startest ist egal ob in der Activity, Service oder Resiver ist gleich, er wird ausgeführt werden.
    Bei einen sich selbst wiedeholenden Alarm kann es unter Android 8 auch zu Problemen kommen.
    da würde sich die JobScheduler-API besser eignen ab API 21 verfügbar.

    Deshalb starte ich den immer wieder neu und beende den Service selber.

    Dem alarmmanager übergibst du einen Pendingintent der einen Intent zu einem Resiver Service hat .
    Der Service prüft ob mobile Daten an sind, schickt eine Benachrichtigung, setzt den Alarm auf die nächsten 3 min, und beendet sich selber.
    Ein Feedback auf Tipps ist auch schön. :P

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von jogimuc ()

  • In einer Activity wirst du das nie zufriedenstellend hin bekommen. Auch deine beispiel app wird es mit Service und Resiver machen. Wenn du es nicht glaubst analysire die apk, lade dir mal Apk Analyse runter und schau was da alles benutzt wird. Habe brauche ich nicht machen ich weiß das es nur so geht.

    Entweder du benutzt den Alarmmanager oder FCM um soetwas wie einen Hardbeat für deinen Service zu haben. Damit er nicht vom System gekillt wird.

    Aber wenn du den Service selber wieder beendest und vom neuen Alarm wieder aufrufst solte es ohne Probleme gehen, habe ich auch schon mal gemacht. Nur solte der Code also der Service nur kurz laufen sonnst kann er auch vom System gekillt werden. Sehe da bei dir kein Problem. Deinen Timer brauchst du somit nicht.

    Dem Intent der den Service aufruft kannst du verschiedene PutExtra geben damit du im service weist wer ihn aufgerufen hat.
    der Allarmmanager oder die Activity. Im Service host du dir den Intent und das putExtra und reagierst etsprechend darauf.
    Die Activity ist somit nur zum steuern des Servises da.
    Soll der Service gleich nach denm booten des Handys activ sein brauchst du einen Resiver der auf die Action BootCompleted wartet. und dann auch den Servis aufruft villeicht auch mit einem eigenen PutExtra .

    Der Service solte kein Intent-service sein also nicht über die onBind an die Activity gebunden sein.



    1) Nun möchte ich aber auch noch, dass meine Kontrolle sofort ausgeführt wird, wenn ich die App wieder in den Vordergrund bringe (zu einem Zeitpunkt MITTEN in den 3-minütigen Intervallen). Mache ich das mit "onRestart" auf folgende Weise,
    und genau das ist die onResume methode ob du es glaubst oder nicht. die wird inmmer wenn du vom hindergrund in den Vordergrund gehst durchlaufen . Klar wird sie auch beim start durchlaufen da musste halt deine Code sogestalten das es da keine Probleme gibt.
    auch wenn du willst das deine benachrichtigung sich löscht wenn die Abb sich beendet kansst du dafür die onStopp oder onDestroy benutzen und die benachrichtigung löschen.



    Meine App sollte also unsichtbar und unschliessbar sein
    Das wird nicht gehen auf keinenfall mit einer Activity . Dafür ist sie nicht gemacht. Unschliessbar gibt es bei Android nicht.
    das System kann dir immer eine Activity einen Service zum teil auch einen Resiver killen.
    Dies kannst du nur duch die genanten tricks ereichen.
    Ein Feedback auf Tipps ist auch schön. :P

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von jogimuc ()

  • Aber einen "ewigen" und unsichtbaren Dienst ist möglich - wie
    geschrieben funktioniert die App "Waterbot" auf meinem Android 8.0 genau
    so und ohne Probleme.
    du sagst es selber Dienst aber keine Activity.

    Wenn du dir die App Waterbot mal mit dem APK Analyzer ansiehst. Wirst du fest stellen das da einige Service, Resiver benutzt werden auch wird da Firebase Cloud Messaging (FCM) benutzt. Du siehst das hier etwas mehr als nur eine Activity notwendig ist.

    Habe mal das Manifest der waterbot apk mit angegangen da siehst du was da alles benutzt wird.
    Dateien
    Ein Feedback auf Tipps ist auch schön. :P

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von jogimuc ()