2012-01-20 5 views
1

Моя цель - запустить службу, которая прослушивает изменения состояния экрана устройства (вкл. Или выкл.) И действует на эти изменения. Я знаю, что это не идеально, но, тем не менее, это то, чего я пытаюсь достичь.Проблемы с ANR с широковещательным приемником в службе

По какой-то причине мой вещательный приемник, похоже, срабатывает при включении экрана, но не тогда, когда он выключается. Кроме того, logcat показывает многочисленные ANR, и, похоже, эта служба неоднократно убивается и перезапускается.

Я последовал за учебник найдено: here

Вот мой соответствующий код:

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 (Изменено согласно предложению, теперь вызывает принудительное закрытие)

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; 
     } 

} 

Приемник широковещательной передачи rted с помощью нажатия кнопки, с помощью этого кода:

IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON); 
    filter.addAction(Intent.ACTION_SCREEN_OFF); 
    BroadcastReceiver mReceiver = new ScreenReceiver(); 
    registerReceiver(mReceiver, filter); 

ответ

3

onStart() не просто устарела, но называется на главном потоке приложения. Определение ANR заключается в том, что вы тратите слишком много времени на основной поток приложений. Переместите логику onStart() в фоновый поток, возможно, путем подкласса IntentService и поместите логику в onHandleIntent().

+0

Благодарим вас за быстрый и информативный ответ. Я попытался реализовать ваше предложение (Код, отредактированный в оригинальном сообщении выше), но теперь я получаю Force Close, когда зарегистрирован приемник. Любые идеи о том, что я делаю неправильно? –

+0

@FrankBozzo: используйте «adb logcat», DDMS или перспективу DDMS в Eclipse для проверки LogCat и просмотра трассировки стека, связанной с вашим «Force Close». – CommonsWare

+0

@FrankBozzo: И, пожалуйста, удалите 'onCreate()' из вашей службы. Я понятия не имею, почему вы думаете, что этот код принадлежит. – CommonsWare

Смежные вопросы