android - Call finish from onPause or onStop when the user destroys the app -
coclusion: ondestroy() not being invoked.
here case:
after launching app, mainactivity
created starts background tracking service. on other hand, user can use checkbox list in main activity select interested routes items of checkbox list represents routes.
after clicking submit button, alarmmanager starts firing data intentservice
class every 30 seconds. subsequently, connection server established , retrieving data mapactivity
started after user redirected automatically mapactivity
.
the user able stop , start background service using icon in menu of both activities. facing problem destroy app in case describes below.
with current code:
- after launching app can stop service in mainactivity , destory app.
- after launching app when change main activity map activity , can stop , start service destroy app opening mapactivity.
- when go following (mainactivity->mapactivity->mainativity->mapactivity) , closed app opening map view app not being destroyed , service not being stoped.
ondestroy()
in mapactivity not being invoked. here app opens gain map view.
but when following: adding startservice(i)(as code snippet 4 lines below) onstart()
in mapactivity after bindservice
can destroy app stoping , starting service problem here dont want start service every time going mainactivity mapactivity since if user stops service in mainactivity must stay off when goes main map.
@override protected void onstart() { super.onstart(); // bind trackingservice. intent intent = new intent(this, trackingservice.class); bindservice(intent, mconnection, context.bind_auto_create); intent = new intent(this, trackingservice.class); startservice(i); }
i know there's no guarantee of when ondestroy() called in activity , maybe should call finish()
inside onpause() or onstop() question how know when call finish() inside onpause() or onstop() since tracking service should run in background until app being destroyed user or user decides stop icon in menu. dont want stop tracking service when user goes in background or everytime onpause()
being called (in case onpause() in mapactivity being called several time in 1 minute).
how can call finish()
onpause()
or onstop()
when user destroys app? how manage in case?
mainactivity:
public class mainactivity extends actionbaractivity implements asynctaskcallback { boolean servicestatus = true; trackingservice mservice; boolean mbound = false; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.route_available); // start trackingservice class. intent = new intent(this, trackingservice.class); startservice(i); } @override public boolean onoptionsitemselected(menuitem item) { system.out.println("abc mainactivity onoptionsitemselected invoked."); switch (item.getitemid()) { case r.id.menu_toggle: if (servicestatus) { item.seticon(r.drawable.off); item.settitle("off"); servicestatus = false; mservice.stoptrackingservice(); } else { item.seticon(r.drawable.on); item.settitle("on"); servicestatus = true; intent = new intent(this, trackingservice.class); startservice(i); system.out.println("abc mainactivity onoptionsitemselected on"); } return super.onoptionsitemselected(item); } } @override protected void onstart() { super.onstart(); // bind trackingservice. intent intent = new intent(this, trackingservice.class); //to start onprepareoptionsmenue() after returning map activity change icon of toggle button. invalidateoptionsmenu(); } @override protected void onstop() { super.onstop(); //13.08.15 // unbind service if (mbound) { unbindservice(mconnection); system.out.println("abc mainactivity onstop() - unbindservice(mconnection) invoked. " + mbound); mbound = false; }else{ system.out.println("abc mainactivity onstop() - unbindservice(mconnection) invoked. " + mbound); } } @override protected void ondestroy() { intent = new intent(this, trackingservice.class); stopservice(i); mservice.stoptrackingservice(); } private serviceconnection mconnection = new serviceconnection(){ @override public void onserviceconnected(componentname name, ibinder service) { localbinder binder = (localbinder) service; mservice = binder.getservice(); mbound = true; } @override public void onservicedisconnected(componentname name) { mbound = false; } }; }
mapactivity
public class mapactivity extends actionbaractivity implements onmapreadycallback, connectioncallbacks, onconnectionfailedlistener { boolean servicestatus; trackingservice mservice; boolean mbound = false; @override protected void onstart() { super.onstart(); servicestatus = getintent().getextras().getboolean("servicestatusextras"); if (servicestatus) { intent = new intent(this, trackingservice.class); bindservice(i, mconnection, context.bind_auto_create); startservice(i); system.out.println("abc mapactivity onstart servicestatus = " + servicestatus); } } /** defines callbacks service binding, passed bindservice() */ private serviceconnection mconnection = new serviceconnection(){ @override public void onserviceconnected(componentname name, ibinder service) { // we've bound localservice, cast ibinder , localservice instance localbinder binder = (localbinder) service; mservice = binder.getservice(); mbound = true; //system.out.println("abc map onserviceconnected() - " + mbound); } @override public void onservicedisconnected(componentname name) { mbound = false; //system.out.println("abc map onservicedisconnected() - mbound"); } }; @override protected void onstop() { super.onstop(); if (mbound) { unbindservice(mconnection); mbound = false; } } @override protected void ondestroy() { super.ondestroy(); markermap.clear(); stopalarm(); if(!servicestatus){ intent = new intent(this, trackingservice.class); stopservice(i); } } @override public boolean onoptionsitemselected(menuitem item) { switch (item.getitemid()) { case r.id.menu_toggle: if (servicestatus) { item.seticon(r.drawable.off); item.settitle("off"); servicestatus = false; if(mservice!=null){ mservice.stoptrackingservice(); } } else { item.seticon(r.drawable.on); item.settitle("on"); servicestatus = true; intent = new intent(this, trackingservice.class); startservice(i); } } return super.onoptionsitemselected(item); } }
trackingservice class:
public class trackingservice extends service implements asynctaskcallback, locationlistener { locationmanager lm; private final ibinder mbinder = new localbinder(); @override public ibinder onbind(intent intent) { return mbinder; } @override public int onstartcommand(intent intent, int flags, int startid) { detectlocation(); return start_not_sticky; } private void detectlocation() { lm = (locationmanager) getsystemservice(context.location_service); lm.requestlocationupdates(locationmanager.gps_provider, 12 * 1000, 0, this); } public class localbinder extends binder { trackingservice getservice() { return trackingservice.this; } } public void stoptrackingservice(){ if(lm != null){ lm.removeupdates(this); } } } }
a classic solution have static counter increased @ each activity "onstart" , decreased on "onpause".
when counter @ 0, app closed
the hard part if have orientation change on first activity, activity destroyed , recreated system, may think app closed (as counter @ 0 in situation)
i have no magic solution particular case
Comments
Post a Comment