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

Ansible warning on jinja2 braces on when -

Parsing a protocol message from Go by Java -

html - How to custom Bootstrap grid height? -