1

My aim is to start a service that listens for changes to the device's screen state (on or off) and acts upon those changes. I am aware that this is not ideal, but, nonetheless, it's what I am trying to accomplish.

For some reason, my broadcast receiver only seems to fire when the screen comes on, but not when it goes off. In addition, logcat reveals numerous ANRs and it appears that the service is being repeatedly killed and restarted.

I followed a tutorial found :here

Here is my relevant code:

ScreenReceiver.java

    public class ScreenReceiver extends BroadcastReceiver {

        private boolean screenOff;

        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
                screenOff = true;
            } else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
                screenOff = false;
            }
            Intent i = new Intent(context, UpdateService.class);
            i.putExtra("screen_state", screenOff);
            context.startService(i);
        }

    }

UpdateService.java (Updated as per suggestion, now causes Force Close)

    public class UpdateService extends IntentService {

        public UpdateService(String name) {
        super(name);
        // TODO Auto-generated constructor stub
    }

        @Override
        public void onCreate() {
            super.onCreate();
            // register receiver that handles screen on and screen off logic
            IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
            filter.addAction(Intent.ACTION_SCREEN_OFF);
            BroadcastReceiver mReceiver = new ScreenReceiver();
            registerReceiver(mReceiver, filter);
        }

        @Override
        protected void onHandleIntent(Intent intent) {
            boolean screenOn = intent.getBooleanExtra("screen_state", false);
            if (!screenOn) {



                String command8 = "*******";
                String command9 = "*********";
                    int timeout = 5;

   try {
   RootTools.Result result = new RootTools.Result() {
   @Override
   public void process(String line) throws Exception {
   // Do something with current line;
   // Maybe store it using setData()
   }

   @Override
   public void onFailure(Exception ex) {
   // Do something if we failed while trying to run a command or read its output

   setError(1);
   }

   @Override
   public void onComplete(int diag) {


   }

   };

   RootTools.sendShell(
   new String[] {

   command8,
   command9},
   timeout,
   result
   );
   if(0 != result.getError())
   return;
   //Do something with getData() if needed.
   } catch (IOException e) {
   //Handle exception
   } catch (InterruptedException e) {
   //Handle exception
   } catch (RootToolsException e) {
   //TODO Auto-generated catch block
   e.printStackTrace();
   }

            } else {

             String command8 = "*******";
                String command9 = "*******";
                 String command10 = "********";
                    String command11 = "********";
                    int timeout = 5;

   try {
   RootTools.Result result = new RootTools.Result() {
   @Override
   public void process(String line) throws Exception {
   // Do something with current line;
   // Maybe store it using setData()
   }

   @Override
   public void onFailure(Exception ex) {
   // Do something if we failed while trying to run a command or read its output

   setError(1);
   }

   @Override
   public void onComplete(int diag) {
   //TODO

   }

   };

   RootTools.sendShell(
   new String[] {

   command8,
   command9,
   command10,
   command11},
   timeout,
   result
   );
   if(0 != result.getError())
   return;
   //Do something with getData() if needed.
   } catch (IOException e) {
   //Handle exception
   } catch (InterruptedException e) {
   //Handle exception
   } catch (RootToolsException e) {
   //TODO Auto-generated catch block
   e.printStackTrace();
   }
            }
        }

        @Override
        public IBinder onBind(Intent arg0) {
            // TODO Auto-generated method stub
            return null;
        }

}

The Broadcast Receiver is started by a button press, with this code:

 IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
    filter.addAction(Intent.ACTION_SCREEN_OFF);
    BroadcastReceiver mReceiver = new ScreenReceiver();
    registerReceiver(mReceiver, filter);
Frank Bozzo
  • 15,033
  • 6
  • 25
  • 29

1 Answers1

3

onStart() is not merely deprecated, but is called on the main application thread. The definition of ANR is that you are spending too much time on the main application thread. Please move your onStart() logic into a background thread, perhaps by subclassing IntentService and putting the logic in onHandleIntent().

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • Thank you for your quick and informative answer. I attempted to implement your suggestion (Code edited in Original Post above) but am now getting a Force Close when the receiver is registered. Any ideas on what I am doing wrong? – Frank Bozzo Jan 21 '12 at 15:14
  • @FrankBozzo: Use `adb logcat`, DDMS, or the DDMS perspective in Eclipse to examine LogCat and look at the stack trace associated with your "Force Close". – CommonsWare Jan 21 '12 at 15:16
  • @FrankBozzo: And please delete `onCreate()` from your service. I have no idea why you think that code belongs there. – CommonsWare Jan 21 '12 at 15:17
  • Okay... I just assumed I did something obviously wrong when implementing your suggestion... I am very much a beginner to all this. – Frank Bozzo Jan 21 '12 at 15:18
  • onCreate code removed. Logcat says "Unable to instantiate service" – Frank Bozzo Jan 21 '12 at 15:25
  • @FrankBozzo: You said you were registering/unregistering your `BroadcastReceiver` in an activity based on a button press. That's a reasonable starting point. An `IntentService` goes away once `onHandleIntent()` wraps up (which is the point). And, since your `IntentService` never was removing its `BroadcastReceiver`, you have a leak. The `IntentService` **solely** should be doing your long-running work, in its background thread, in `onHandleIntent()`. – CommonsWare Jan 21 '12 at 15:26
  • @FrankBozzo: You do not have a zero-parameter public constructor on your service. – CommonsWare Jan 21 '12 at 15:27
  • Thank you for you help. I am reading over all the Services documentation I can find, but am still unclear on what you mean by a ZERO-PARAMETER public constructor... could you please give me an example. – Frank Bozzo Jan 21 '12 at 15:58