time - Android: How to set a timer that notifies you, even if app is minimized? -


i want ability set reusable timer (e.g. 20 seconds) , have start counting down, minimize app, else, , have timer still notify me. timer should start / stop / pause / reset-able.

i've seen alarmmanager read seems broken on several devices. there more robust solution?

edit: trying service

the manifest:

<?xml version="1.0" encoding="utf-8"?> <manifest package="com.packagename.timertest"           xmlns:android="http://schemas.android.com/apk/res/android">      <application         android:allowbackup="true"         android:icon="@mipmap/ic_launcher"         android:label="@string/app_name"         android:roundicon="@mipmap/ic_launcher_round"         android:supportsrtl="true"         android:theme="@style/apptheme">         <activity android:name=".mainactivity">             <intent-filter>                 <action android:name="android.intent.action.main"/>                  <category android:name="android.intent.category.launcher"/>             </intent-filter>         </activity>          <service android:name=".timerservice"                  android:exported="false"/>     </application>  </manifest> 

mainactivity launching fragment:

public class mainactivity extends appcompatactivity {     private button launchtimerpanelbutton;     private fragmentmanager fragmentmanager;      @override     protected void oncreate(bundle savedinstancestate) {         super.oncreate(savedinstancestate);         setcontentview(r.layout.activity_main);         fragmentmanager = getsupportfragmentmanager();          launchtimerpanelbutton = (button) findviewbyid(r.id.launch_timer_button);         launchtimerpanelbutton.setonclicklistener(new view.onclicklistener() {             @override             public void onclick(view v) {                 timerdialogfragment dialogfragment = timerdialogfragment.newinstance(10);                 dialogfragment.setstyle(dialogfragment.style_normal, r.style.customdialog);                 dialogfragment.show(fragmentmanager,"");             }         });     } } 

the xml mainactivity:

<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.constraintlayout     xmlns:android="http://schemas.android.com/apk/res/android"     xmlns:app="http://schemas.android.com/apk/res-auto"     xmlns:tools="http://schemas.android.com/tools"     android:layout_width="match_parent"     android:layout_height="match_parent"     tools:context="com.packagename.timertest.mainactivity">      <button         android:id="@+id/launch_timer_button"         android:layout_width="match_parent"         android:layout_height="wrap_content"         android:text="launch timer panel"/>  </android.support.constraint.constraintlayout> 

the dialogfragment:

public class timerdialogfragment extends dialogfragment {     private static final string argument_num_seconds = "state_num_seconds";     private static final string state_num_seconds = "state_num_seconds";     public static final string state_is_broadcast_receiver_registered = "state_is_broadcast_receiver_registered";     private int numsecondsinitial;     private int numseconds;     private textview secondsremainingtextview;     private button startbutton;     private button pausebutton;     private button resetbutton;     private button closebutton;     private broadcastreceiver resttimerreceiver;     private boolean isbroadcastreceiverregistered;      public static timerdialogfragment newinstance(int numseconds) {         bundle args = new bundle();         timerdialogfragment fragment = new timerdialogfragment();         args.putint(argument_num_seconds, numseconds);         fragment.setarguments(args);         return fragment;     }      @override     public void oncreate(@nullable bundle savedinstancestate) {         super.oncreate(savedinstancestate);         numsecondsinitial = getarguments().getint(argument_num_seconds);         if (savedinstancestate == null) {             numseconds = numsecondsinitial;         }         else {             numseconds = savedinstancestate.getint(state_num_seconds);         }          isbroadcastreceiverregistered = false;         if (savedinstancestate != null) {             isbroadcastreceiverregistered = savedinstancestate.getboolean(state_is_broadcast_receiver_registered);         }          resttimerreceiver = new broadcastreceiver() {             @override             public void onreceive(context context, intent intent) {                 //???????             }         };         registerbroadcastreceiver();     }      @nullable     @override     public view oncreateview(layoutinflater inflater, @nullable viewgroup container, @nullable bundle savedinstancestate) {         view contentview = inflater.inflate(r.layout.dialogfragment_timer, container, false);         getdialog().settitle("timer");          secondsremainingtextview = (textview) contentview.findviewbyid(r.id.seconds_remaining_textview);         secondsremainingtextview.settext(numseconds + "");          startbutton = (button) contentview.findviewbyid(r.id.start_button);         pausebutton = (button) contentview.findviewbyid(r.id.pause_button);         resetbutton = (button) contentview.findviewbyid(r.id.reset_button);         closebutton = (button) contentview.findviewbyid(r.id.close_button);           startbutton.setonclicklistener(new view.onclicklistener() {             @override             public void onclick(view v) {              }         });          pausebutton.setonclicklistener(new view.onclicklistener() {             @override             public void onclick(view v) {              }         });          resetbutton.setonclicklistener(new view.onclicklistener() {             @override             public void onclick(view v) {              }         });          closebutton.setonclicklistener(new view.onclicklistener() {             @override             public void onclick(view v) {                 //end timer first?                 unregisterbroadcastreceiver();                 dismiss();             }         });          return contentview;     }      @override     public void onsaveinstancestate(bundle outstate) {         outstate.putint(state_num_seconds, numseconds);         super.onsaveinstancestate(outstate);     }      @override     public void onresume() {         registerbroadcastreceiver();         super.onresume();     }      @override     public void onpause() {         unregisterbroadcastreceiver();         super.onpause();     }      @override     public void ondestroy() {         unregisterbroadcastreceiver();         super.ondestroy();     }       private void registerbroadcastreceiver() {         if (!isbroadcastreceiverregistered) {             localbroadcastmanager.getinstance(getactivity()).registerreceiver(resttimerreceiver, new intentfilter(timerservice.timer_service));             isbroadcastreceiverregistered = true;         }     }      private void unregisterbroadcastreceiver() {         if (isbroadcastreceiverregistered) {             isbroadcastreceiverregistered = false;             localbroadcastmanager.getinstance(getactivity()).unregisterreceiver(resttimerreceiver);         }     }  } 

its layout:

<?xml version="1.0" encoding="utf-8"?> <linearlayout xmlns:android="http://schemas.android.com/apk/res/android"               android:orientation="vertical"               android:layout_width="match_parent"               android:layout_height="wrap_content"               android:padding="10dp"     android:gravity="center">       <textview         android:id="@+id/seconds_remaining_textview"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:layout_gravity="center"         android:textappearance="?android:attr/textappearancelarge"         android:gravity="center"         android:text="10"/>      <button         android:id="@+id/start_button"         android:layout_margintop="20dp"         android:layout_width="match_parent"         android:layout_height="wrap_content"         android:layout_gravity="center"         android:textappearance="?android:attr/textappearancemedium"         android:gravity="center"         android:text="start timer"/>       <button         android:id="@+id/pause_button"         android:layout_margintop="20dp"         android:layout_width="match_parent"         android:layout_height="wrap_content"         android:layout_gravity="center"         android:textappearance="?android:attr/textappearancemedium"         android:gravity="center"         android:text="pause timer"/>       <button         android:id="@+id/reset_button"         android:layout_margintop="20dp"         android:layout_width="match_parent"         android:layout_height="wrap_content"         android:layout_gravity="center"         android:textappearance="?android:attr/textappearancemedium"         android:gravity="center"         android:text="reset timer"/>      <button         android:id="@+id/close_button"         android:layout_margintop="20dp"         android:layout_width="match_parent"         android:layout_height="wrap_content"         android:layout_gravity="center"         android:textappearance="?android:attr/textappearancemedium"         android:gravity="center"         android:text="close / end timer"/>  </linearlayout> 

the service:

public class timerservice extends service {     private string log_tag = timerservice.class.getsimplename();     public static final string timer_service = "timer_service";      @override     public void oncreate() {         super.oncreate();         log.i(log_tag, "oncreate");     }      @override     public int onstartcommand(intent intent, int flags, int startid) {         log.i(log_tag, "in onstartcommand");         new thread(new runnable() {             public void run() {                 //something             }         }).start();         return start_redeliver_intent;     }      @nullable     @override     public ibinder onbind(intent intent) {         log.i(log_tag, "onbind");         return null;     }      @targetapi(build.version_codes.ice_cream_sandwich)     @override     public void ontaskremoved(intent rootintent) {         super.ontaskremoved(rootintent);         log.i(log_tag, "in ontaskremoved");     }      @override     public void ondestroy() {         super.ondestroy();         log.i(log_tag, "in ondestroy");     } } 

if one-time process, think service best option. can whatever want there and, when process finished, send broadcast notify has finished.


Comments

Popular posts from this blog

node.js - Node js - Trying to send POST request, but it is not loading javascript content -

javascript - Replicate keyboard event with html button -

javascript - Web audio api 5.1 surround example not working in firefox -