java - Why is my background service or my broadcast receiver being killed with main activity? -


i want independent running service pushbullet, smartlockscreen or whatsapp has, waiting event happen. have tried foreground service, returning start_sticky in onstartcommand, restarting service in ontaskremoved , running service in separate process using android:process.

my service class:

public class callservice  extends service {  @override public ibinder onbind(intent intent) {     // todo auto-generated method stub     return null; }  @override public int onstartcommand (intent intent, int flags, int startid){     notificationcompat.builder builder = new notificationcompat.builder(this);     builder.setsmallicon(r.drawable.icon)             .setcontenttitle("title")             .setcontenttext("text")             .setautocancel(true)             .setongoing(true);     intent startintent = new intent(this, mainactivity.class);     pendingintent contentintent = pendingintent.getactivity(this, 1, startintent, 0);     builder.setcontentintent(contentintent);     this.startforeground(1, builder.build());     super.onstartcommand(intent, flags, startid);     return start_sticky; }  @override public void oncreate() {     super.oncreate(); }  @override public void ondestroy() {     super.ondestroy();  } @override public void ontaskremoved(intent rootintent){     intent restartserviceintent = new intent(getapplicationcontext(), this.getclass());     restartserviceintent.setpackage(getpackagename());      pendingintent restartservicependingintent = pendingintent.getservice(getapplicationcontext(), 1, restartserviceintent, pendingintent.flag_one_shot);     alarmmanager alarmservice = (alarmmanager) getapplicationcontext().getsystemservice(context.alarm_service);     alarmservice.set(             alarmmanager.elapsed_realtime,             systemclock.elapsedrealtime() + 1000,             restartservicependingintent);      super.ontaskremoved(rootintent); } 

my androidmanifest.xml

<service android:name=".callservice" android:persistent="true">             <intent-filter>                 <action android:name="cz.volamakler.callservice" />             </intent-filter> </service>     <receiver android:name=".callreceiver">         <intent-filter>             <action android:name="android.intent.action.phone_state" />         </intent-filter>         <intent-filter>             <action android:name="android.intent.action.new_outgoing_call" />         </intent-filter>     </receiver> 

i tried using broadcast receiver , gets killed main activity too.

    public abstract class phonecallreceiver extends broadcastreceiver {      //the receiver recreated whenever android feels it.  need static variable remember data between instantiations      private static int laststate = telephonymanager.call_state_idle;     private static date callstarttime;     private static boolean isincoming;     private static string savednumber;  //because passed incoming valid in ringing       @override     public void onreceive(context context, intent intent) {          //we listen 2 intents.  new outgoing call tells of outgoing call.  use number.         if (intent.getaction().equals("android.intent.action.new_outgoing_call")) {             savednumber = intent.getextras().getstring("android.intent.extra.phone_number");         }         else{             string statestr = intent.getextras().getstring(telephonymanager.extra_state);             string number = intent.getextras().getstring(telephonymanager.extra_incoming_number);             int state = 0;             if(statestr.equals(telephonymanager.extra_state_idle)){                 state = telephonymanager.call_state_idle;             }             else if(statestr.equals(telephonymanager.extra_state_offhook)){                 state = telephonymanager.call_state_offhook;             }             else if(statestr.equals(telephonymanager.extra_state_ringing)){                 state = telephonymanager.call_state_ringing;             }              oncallstatechanged(context, state, number);         }     }      //derived classes should override these respond specific events of interest     protected void onincomingcallstarted(context ctx, string number, date start){}     protected void onoutgoingcallstarted(context ctx, string number, date start){}     protected void onincomingcallended(context ctx, string number, date start, date end){}     protected void onoutgoingcallended(context ctx, string number, date start, date end){}     protected void onmissedcall(context ctx, string number, date start){}      //deals actual events      //incoming call-  goes idle ringing when rings, offhook when it's answered, idle when hung     //outgoing call-  goes idle offhook when dials out, idle when hung     public void oncallstatechanged(context context, int state, string number) {         if(laststate == state){             //no change, debounce extras             return;         }         switch (state) {             case telephonymanager.call_state_ringing:                 isincoming = true;                 callstarttime = new date();                 savednumber = number;                 onincomingcallstarted(context, number, callstarttime);                 break;             case telephonymanager.call_state_offhook:                 //transition of ringing->offhook pickups of incoming calls.  nothing done on them                 if(laststate != telephonymanager.call_state_ringing){                     isincoming = false;                     callstarttime = new date();                     onoutgoingcallstarted(context, savednumber, callstarttime);                 }                 break;             case telephonymanager.call_state_idle:                 //went idle-  end of call.  type depends on previous state(s)                 if(laststate == telephonymanager.call_state_ringing){                     //ring no pickup-  miss                     onmissedcall(context, savednumber, callstarttime);                 }                 else if(isincoming){                     onincomingcallended(context, savednumber, callstarttime, new date());                 }                 else{                     onoutgoingcallended(context, savednumber, callstarttime, new date());                 }                 break;         }         laststate = state;     } }  public class callreceiver extends phonecallreceiver {      @override     protected void onincomingcallstarted(context ctx, string number, date start) {         toast.maketext(ctx, "call!", toast.length_long).show();     }      @override     protected void onoutgoingcallstarted(context ctx, string number, date start) {     }      @override     protected void onincomingcallended(context ctx, string number, date start, date end) {     }      @override     protected void onoutgoingcallended(context ctx, string number, date start, date end) {     }      @override     protected void onmissedcall(context ctx, string number, date start) {     } } 

this happening because running service in same ui thread. looper used same of application's ui thread starting service. need following:

create seperate handler thread. tasks inside handlemessage.

  public class callservice  extends service {             private looper mservicelooper;           private servicehandler mservicehandler;            // handler receives messages thread           private final class servicehandler extends handler {               public servicehandler(looper looper) {                   super(looper);               }               @override               public void handlemessage(message msg) {                   // work here, download file.                   // our sample, sleep 5 seconds.                   long endtime = system.currenttimemillis() + 5*1000;                   while (system.currenttimemillis() < endtime) {                       synchronized (this) {                           try {                               wait(endtime - system.currenttimemillis());                           } catch (exception e) {                           }                       }                   }                   // stop service using startid, don't stop                   // service in middle of handling job                   stopself(msg.arg1);               }           }             @override             public ibinder onbind(intent intent) {                 // todo auto-generated method stub                 return null;             }              @override             public int onstartcommand (intent intent, int flags, int startid){ // each start request, send message start job , deliver       // start id know request we're stopping when finish job       message msg = mservicehandler.obtainmessage();       msg.arg1 = startid;       mservicehandler.sendmessage(msg);                  return start_sticky;             }            @override       public void oncreate() {         // start thread running service.  note create         // separate thread because service runs in process's         // main thread, don't want block.  make         // background priority cpu-intensive work not disrupt our ui.         handlerthread thread = new handlerthread("servicestartarguments",                 process.thread_priority_background);         thread.start();          // handlerthread's looper , use our handler         mservicelooper = thread.getlooper();         mservicehandler = new servicehandler(mservicelooper);       }             @override             public void ondestroy() {                 super.ondestroy();              }             @override             public void ontaskremoved(intent rootintent){                 intent restartserviceintent = new intent(getapplicationcontext(), this.getclass());                 restartserviceintent.setpackage(getpackagename());                  pendingintent restartservicependingintent = pendingintent.getservice(getapplicationcontext(), 1, restartserviceintent, pendingintent.flag_one_shot);                 alarmmanager alarmservice = (alarmmanager) getapplicationcontext().getsystemservice(context.alarm_service);                 alarmservice.set(                         alarmmanager.elapsed_realtime,                         systemclock.elapsedrealtime() + 1000,                         restartservicependingintent);                  super.ontaskremoved(rootintent);             }             } 

i hope helps.


Comments

Popular posts from this blog

routing - AngularJS State management ->load multiple states in one page -

python - GRASS parser() error -

json - Gson().fromJson(jsonResult, Myobject.class) return values in 0's -