活动从睡眠模式立即开始关闭?

时间:2014-06-23 16:10:57

标签: android wakelock keyguard

我有一个应用程序,它是一种闹钟。我有一个奇怪的问题。

原则很简单:闹钟管理员发送广播启动服务和活动。

该服务使手机振动10秒,然后杀死活动本身。 该活动显示一个解雇按钮。如果单击它,它将停止服务及其自身。

如果手机开机时收到广播,则表示正常(活动开始,手机振动)。

如果在手机处于睡眠模式时收到广播,则活动开始并立即停止(您实际上无法在屏幕上看到它,除非你把Thread.sleep放在某个地方)。服务很好。

我不明白为什么活动在创建后就停止了?

在logcat中,我有这两个最后一行,当它工作时我没有:

06-23 18:07:58.349: I/ActivityManager(305): Displayed com.example.testproject/.AlarmeScreenOffActivity: +100ms
06-23 18:07:58.349: I/power(305): *** set_screen_state 1
06-23 18:07:58.359: D/kernel(145): [557082.194793] request_suspend_state: wakeup (3->0) at 557080649502843 (2014-06-23 16:07:58.358764661 UTC)

感谢。


这是接收者中的代码:

        WakeLockManager.acquireWakeLock(context);

        Intent closeDialogs = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
        context.sendBroadcast(closeDialogs);

        Intent alarmeActivity = new Intent(context,
                AlarmeScreenOffActivity.class);
        alarmeActivity.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(alarmeActivity);

        Intent playAlarm = new Intent(context, AlarmeSonVibration.class);
        context.startService(playAlarm);

活动:

private BroadcastReceiver mReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (MyBroadcastReceiver.ALARM_TIMEOUT.equals(intent.getAction())) {
            dismiss();
        }
    }
};

@Override
protected void onCreate(Bundle icicle) {
    super.onCreate(icicle);     
    updateLayout();     
    registerReceiver(mReceiver, new IntentFilter(MyBroadcastReceiver.ALARM_TIMEOUT));
}

private void updateLayout() {   

    requestWindowFeature(android.view.Window.FEATURE_NO_TITLE); 
    this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN | 
            WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD | 
            WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | 
            WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON,
            WindowManager.LayoutParams.FLAG_FULLSCREEN | 
            WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD | 
            WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | 
            WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);

    setContentView(R.layout.alarm_alert);

    Button dismissbouton = (Button) findViewById(R.id.dismiss);
    dismissbouton.setText("Dismiss");

    dismissbouton.setOnClickListener(new Button.OnClickListener() {
        public void onClick(View v) {                   
            dismiss();
        }
    });

}

private void dismiss() {
    Intent playAlarm = new Intent(this, AlarmeSonVibration.class);
    stopService(playAlarm);
    finish();
}

@Override
public void onDestroy() {
    super.onDestroy();
    unregisterReceiver(mReceiver);  
}

服务:

private static int ALARM_TIMEOUT_SECONDS = 10;
private static final long[] sVibratePattern = new long[] { 500, 300 };
private boolean mPlaying = false;
private Vibrator mVibrator;

private static final int TIMEOUT = 1001;    
private Handler mHandler = new Handler() {
    public void handleMessage(Message msg) {
        switch (msg.what) {
        case TIMEOUT:
            sendTimeOutBroadcast();
            stopSelf();
            break;
        }
    }
};

@Override
public void onCreate() {
    WakeLockManager.acquireWakeLock(this);      
    mVibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);      
}

@Override
public void onDestroy() {
    super.onDestroy();
    stop();
    WakeLockManager.releaseWakeLock();
}


@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    if (intent == null) {
        stopSelf();
        return START_NOT_STICKY;
    }
    play();
    return START_STICKY;
}

private void sendTimeOutBroadcast() {
    Intent alarmtimeout = new Intent(MyBroadcastReceiver.ALARM_TIMEOUT);
    sendBroadcast(alarmtimeout);
}

private void play() {
    stop();
    mVibrator.vibrate(sVibratePattern, 0);
    enableTimeOut();
    mPlaying = true;
}

public void stop() {
    if (mPlaying) {
        mPlaying = false;
        mVibrator.cancel();
    }
    disableTimeOut();
}

private void enableTimeOut() {
    mHandler.sendMessageDelayed(mHandler.obtainMessage(TIMEOUT, true),
            1000 * ALARM_TIMEOUT_SECONDS);
}

private void disableTimeOut() {
    mHandler.removeMessages(TIMEOUT);
}

编辑:

经过一些其他测试后,即使没有启动该服务,该应用似乎也不希望我的活动留在ui上。

广播会触发活动,设备会唤醒并运行活动,但随后它会关闭(它会立即从onresume转到onpause)。

使用或不使用键盘锁,结果是一样的,我的活动开始和停止。

应该简单吗?我只是尝试通过分割广播来从睡眠模式运行活动。

1 个答案:

答案 0 :(得分:2)

好吧,即使我不完全理解发生了什么,我也能解决我的问题。

在从睡眠模式开始的活动中,onStop方法是:

@Override
protected void onStop() {
    super.onStop();
    if (!isFinishing()) {
        // Don't hang around.
        finish();
    }
}

这与android alarmclock源代码中的方法相同。 如果我改为:

@Override
protected void onStop() {
    super.onStop();
    if (!isFinishing()) {
        // Don't hang around.
        //finish();
    }
}

它在工作......

我看到为什么onStop正在被召唤。 从睡眠模式运行此活动时,似乎是android,创建它然后将其设置为停止。 然后,finish()会破坏它。

我仍然不知道为什么Android希望活动继续停止(以及为什么它不是闹钟的原始源代码中的错误),但现在它正在工作,我&# 39;快乐。

感谢那些试图帮助我的人。