Подтвердить что ты не робот

Почему метод onPause вызывается сразу после onCreate

Я пишу приложение, которое показывает активность в определенное время.

Я запускаю действие из службы с таким кодом:

intent.setClass(context, FakeAction.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);

в методе onCreate FakeAction Мне требуется пробуждение устройства и запуск звукового сообщения:

getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);

В onCreate есть много кода, чтобы отображать информацию на экране и запускать звуковое сообщение.

Вот метод onPause:

@Override
protected void onPause()
{
    Log.i(TAG, "onPause");

    //Stop mediaPlayer
    if(mp != null)
    {
        if(mp.isPlaying())mp.stop();
        mp.release();
        mp = null;
    }

    //Restore volume
    if(audioManager != null)
    {
        audioManager.setStreamVolume(AudioManager.STREAM_ALARM, savedVolume, 0);
    }

    //Stop minute timer
    handler.removeCallbacks(minuteReceiver);

    super.onPause();
}

К сожалению, метод onPause() вызывается сразу после onCreate. Поэтому мое звуковое сообщение немедленно прекращается.

Но если действие запускается, когда экран не заблокирован, onPasue() не вызывается сразу после onCreate();

Даже если я комментирую все строки getWindow(). addFlags(), то onPause() вызывается после onCreate(), когда экран заблокирован.

Вопрос в том, почему onPause вызывается сразу после onCreate? Как я могу отличить немедленный вызов метода onPause() и вызова onPause(), когда пользователь нажимает кнопку "Назад"?

Ниже приведен код действия. Я использую шаблон MVP, поэтому основной код находится в презентаторе. Но даже если я прокомментирую все вызовы ведущего (как в этом примере), onPause() вызывается сразу после onCreate()

Возможно ли, что я начал работу в AsyncTask? AsyncTask запускает сервис формы. Служба прекращается после завершения AsyncTask.

public class FakeAction extends RoboActivity
                            implements 
                            View.OnClickListener
                            ,AlarmAction
{
    private static final String TAG = "TA FakeAction";

    @InjectView(R.id.aa_btn_Stop)       Button btnStop;
    @InjectView(R.id.aa_btn_Snooze)     Button btnSnooze;
    @InjectView(R.id.aa_tv_CurTime)     TextView tvCurTime;
    @InjectView(R.id.aa_tv_CurDate)     TextView tvCurDate;
    @InjectView(R.id.aa_tv_AlarmName)   TextView tvAlarmName;

    @Inject public AlarmActionPresenter presenter;

    private Exception   ex;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        Log.i(TAG, "onCreate");

        super.onCreate(savedInstanceState);

        getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);

        setContentView(R.layout.alarm_action);

        try
        {
            //presenter.onCreate(this);
        }
        catch(Exception ex)
        {
            this.ex = ex;
            Log.e(TAG, "onCreate",  ex);
        }

        btnStop.setOnClickListener(this);
        btnSnooze.setOnClickListener(this);


    }

    @Override
    protected void onPause()
    {
        Log.i(TAG, "onPause");

        //presenter.onPause();

        super.onPause();
    }

    @Override
    public void onClick(View v)
    {
        Log.i(TAG, "onClick");

        //presenter.onClick(v.getId());

    }

    @Override
    public Bundle getIntentBundle()
    {
        return getIntent().getExtras();
    }

    @Override
    public void setAlarmName(String alarmName)
    {
        tvAlarmName.setText(alarmName);
    }

    @Override
    public String getAlarmName()
    {
        return tvAlarmName.getText().toString();
    }

    @Override
    public void setCurTime(String curTime)
    {
        tvCurTime.setText(curTime);
    }

    @Override
    public String getCurTime()
    {
        return tvCurTime.getText().toString();
    }

    @Override
    public void setCurDate(String curDate)
    {
        tvCurDate.setText(curDate);
    }

    @Override
    public String getCurDate()
    {
        return tvCurDate.getText().toString();
    }



    @Override
    public IAssetFileDescriptorMockable openFd(String assetName) throws IOException
    {
        Log.i(TAG, "openFd");
        return new AssetFileDescriptorMockable(getAssets().openFd(assetName));
    }

}
4b9b3361

Ответ 1

Я нашел решение моей проблемы.

Причиной, по которой onPause вызывается после onCreate, является ActivityManager. В журнале я нашел строку сразу после onCreate: "Тайм-аут паузы активности для HistoryRecord" Итак, следующие события произошли в моей деятельности:

  1. OnCreate()
  2. OnStart()
  3. onResume()
  4. Тайм-аут приостановки активности для HistoryRecord
  5. OnPause()
  6. onResume()

Я не знаю, как предотвратить "Тайм-аут паузы активности для HistoryRecord", но я изменил свое приложение, чтобы оно запускало звуковое сообщение в onResume(). Даже если он остановлен в onPause(), он снова запускается в следующем onResume().

Ответ 2

Вот что, я думаю, происходит, тогда: ваш сервис создает вашу активность, и ваша деятельность делает несколько вещей, например, пробуждение экрана и отказ от блокировки клавиатуры. Но это не мгновенно, а это значит, что активность keyguard, вероятно, разбудилась до того, как ее уволили, тем самым приостановив вашу деятельность на короткое время.

Я думаю, что вы должны это сделать: http://thinkandroid.wordpress.com/2010/01/24/handling-screen-off-and-screen-on-intents/

Справьтесь с этим, используя намерение. Вы поймете намерение сказать, что экран включен, и намерение выключить экран.

Цикл будет работать так, я думаю:

  • Вы создадите свою активность.
  • Ваша деятельность будет продолжаться. При попытке отклонить блокировку клавиатуры и настроить несколько вещей.
  • Ваша активность снова проснется.
  • Ваша активность будет получать экран при намерении

Это означает: когда вызывается onPause, экран выключен! Значение: вам нужен только флаг, и если этот флаг говорит, что экран по-прежнему выключен, вы не приостанавливаете музыку.

Это немного грязно, но должно отлично работать.

Ответ 3

Я решил свою проблему, проверив, включен ли экран с помощью следующего кода:

    PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);  
    if (!powerManager.isScreenOn()){
       return;
    }

Используйте код, если прекращаете звуковую активность, когда нажимаете кнопку домой. onPause не активен, пока экран не включен.

  @Override
    protected void onPause() {

        PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
        if (powerManager.isScreenOn()){

            Log.e("Test two", "****");
            Intent i = new Intent(this, RingtonePlayingService.class);
            stopService(i);

            finish();
        }


        super.onPause();
    }

Таким образом, код в методе onPause выполняется только при включенном экране. Когда экран включается и вызывается onPause, метод isScreenOn из PowerManager возвращает false.

Ответ 4

Запустите намерение, которое проверит, выходит ли пользователь и привязывает его к вашей кнопке выхода. Я все еще не уверен, что вы хотите, поскольку код является неполным.

Ответ 5

You can distinguish onPause() call between Acticity itself and back button press.

onBackPressed(){
// set isBackPressed = true;
}

onPause(){
if(isBackPressed ){
// exit due to back pressed.
}else{
// normal exit.
}
}

Ответ 6

Если у вас есть ES File Explorer, тогда FORCE STOP. Так или иначе, они прерывают жизненный цикл вашего приложения (комментарии предполагают какое-то наложение).

Моя проблема с тем, что onResume вызывался дважды, была из-за того, что onPause как-то вызывали после создания действия... что-то прерывало мое приложение.

И это происходит только после первого открытия после установки или сборки из студии.

Я получил подсказку из другого поста и узнал, что это из-за ES File Explorer. Почему onResume(), кажется, вызывается дважды?

Как только я принудительно прекращаю работу ES File Explorer, такой сбой больше не происходит... расстраивает, когда узнает много других предложенных решений. Так что остерегайтесь любых других прерывающих приложений, таких как это.