Reputation: 15403
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);
Upvotes: 2
Views: 6900
Reputation: 1007359
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()
.
Upvotes: 3