当前位置: 首页 > 知识库问答 >
问题:

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

鲜于允晨
2023-03-14

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

原理很简单:警报管理器发送一个广播,启动服务和活动。

该服务使手机振动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 上。

广播触发活动,设备唤醒并运行活动,但随后关闭(立即从恢复到暂停)。

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

它应该是简单的?我只是尝试运行一个活动从睡眠模式触发广播。

共有1个答案

彭鸿哲
2023-03-14

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

在从睡眠模式启动的活动中,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();
    }
}

它在工作……

发生的事情是,我正在寻找为什么调用on停止。看起来android在从睡眠模式运行此活动时,创建了它,然后将其设置为on停止。然后,完成()将销毁它。

我仍然不明白为什么Android希望这个活动停止(为什么它不是alarmclock原始源代码中的一个错误),但是现在它工作了,我很高兴。

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

 类似资料:
  • 我有一个活动需要在启动时打开屏幕(如果关闭)。所以在onCreate中,我有: 使用这个与wakelock在扩频接收器的帮助下,我能够使我的活动显示,每当它从广播接收器开始。 但问题很奇怪,活动生命周期以这种方式调用,onPause()和onResume在开始活动后立即执行 创建时 开始时 继续 打开暂停 onStop(停止) 开始时 继续 所以问题出在启动和恢复调用两次时,停止时也调用,我想在

  • 自动睡眠 于一定时间内没有操作后,会自动进入睡眠模式以节省电力。 关 不自动进入睡眠模式 5分后 5分钟以后进入睡眠模式 10分后 10分钟以后进入睡眠模式 15分后 15分钟以后进入睡眠模式 提示 于进行以下操作时,自动睡眠机能可能会暂时失效。 连接交流电转换器时 玩游戏时 播放影像时 播放音乐时 播放幻灯片秀时 使用USB连接线与外接装置连接,启用USB模式时 聆听网上电台时* *  部份网上

  • 我有两个模块。应用程序和模块测试。模块应用程序包含带按钮的主活动。模块测试包含主要活动二。我想通过点击按钮从模块应用程序运行Test/MainActivity。但Android仍然无法从模块测试中看到主要活动。见下文。 模块应用清单: 模块测试清单: 在模块app MainActivity中为单击按钮和运行第二个活动编码: 在控制台我得到一个错误: 带系统。错误:java。lang.ClassNo

  • 我有两个碎片,两个碎片上都有一个按钮。当我按下按钮时,我想开始一项新的活动。但我不能让它工作。 我得到的错误:这里的错误:类型不匹配:无法从mFragmentFavorite转换为片段 我做错了什么? 我的碎片寻呼机适配器 收藏夹 如果FavoriteActivity扩展了片段,那么错误就消失了,但是我在findViewById(R.id.mainFavorite)处得到了一个错误 错误为 fin

  • 我已经想从我的Main活动启动我的RecipientFra法规,并从我的Main活动将数据传递到Fra法规。这是我实现的代码。但是碎片没有开始。 我还想知道如何传递intent.set数据,并在碎片中获取数据。目前我有以下代码: 受体片段 主要活动