【问题标题】:PopUp Activity starts again when it is started from "recent apps"PopUp Activity 从“最近的应用程序”启动时再次启动
【发布时间】:2014-05-07 05:35:17
【问题描述】:

我有一个 PopUp 活动,它在 AlarmManager 收到警报时启动。

AlarmReceiver 扩展了 WakefulBroadcastReceiver:

@Override
public void onReceive(Context context, Intent intent) {
    Intent service = new Intent(context, AlarmService.class);
    service.putExtras(intent);

    // Start the service, keeping the device awake while it is launching.
    startWakefulService(context, service);
}

AlarmService 扩展 IntentService:

@Override
protected void onHandleIntent(Intent intent) {

    Intent i = new Intent();
    i.setClass(this, PopUpActivity.class);
    startActivity(i);
    AlarmReceiver.completeWakefulIntent(intent);
}

弹出活动:

@Override
protected void onCreate(final Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);


    getWindow().setFlags(LayoutParams.FLAG_NOT_TOUCH_MODAL, LayoutParams.FLAG_NOT_TOUCH_MODAL);
    getWindow().setFlags(LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);
    setContentView(R.layout.layout_dialog);



    PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
    PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, ClientConstants.WAKE_LOCK_NOTIFICATION);
    // Acquire the lock
    wl.acquire();

    if (canVibrate){
        vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
        vibrator.vibrate(new long[]{ 0, 200, 500 },0);
    }
    if (canRing){
        mediaPlayer = new MediaPlayer();
        try {
            mediaPlayer.setDataSource(this, getAlarmUri());
            final AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
            if (audioManager.getStreamVolume(AudioManager.STREAM_ALARM) != 0) {
                mediaPlayer.setAudioStreamType(AudioManager.STREAM_ALARM);
                mediaPlayer.prepare();
                mediaPlayer.start();
            }
        } catch (IOException e) {
        }
    }

    findViewById(R.id.dialog_ok_button).setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            stopRinging();
            finish();
        }
    });
    // Release the lock
    wl.release();
}
private void stopRinging(){
    if (canRing && mediaPlayer.isPlaying())
        mediaPlayer.stop();
    if (canVibrate){
        vibrator.cancel();
    }
}

PopUpActivity 从警报管理器启动。如果在应用程序不是活动应用程序时启动 PopUpActivity,并且如果用户按下“确定按钮”,则活动消失。到目前为止,这里没有任何问题。 问题是,如果用户打开最近的应用程序屏幕并选择了一个新的 PopUpActivity 活动,则会再次启动。我怎样才能摆脱这个问题?

【问题讨论】:

  • 您能否提供更多详细信息。当用户从最近的应用屏幕中选择时,您的要求是什么。

标签: android broadcastreceiver alarmmanager


【解决方案1】:

在清单中声明 PopupActivity 时,请确保包含 android:noHistory="true"。这意味着一旦你打开“最近”,弹出的活动就会被遗忘,当你重新打开应用程序时,你只会回到原来的位置。

【讨论】:

    【解决方案2】:

    当用户按下Ok 按钮时,Activity.finish() 方法被调用。这会导致Activity 被销毁。因此,当用户从最近的应用部分选择应用时,Activity 会再次创建。

    如果您不想破坏 Activity 但想将其置于后台,请将 Activity.finish() 方法替换为 Activity.moveTaskToBack(boolean)

    findViewById(R.id.dialog_ok_button).setOnClickListener(new OnClickListener() {
    
        @Override
        public void onClick(View v) {
            stopRinging();
            moveTaskToBack(true);
        }
    });
    

    您需要处理Activity由于内存不足和配置更改而被杀死后重新启动的情况。

    您可以在Activity 启动Intent 标志中设置FLAG_ACTIVITY_SINGLE_TOP,以确保如果新实例已经在历史堆栈的顶部运行,则不会创建它。

    【讨论】:

    • 对不起,我当时不能奖励你的赏金,我现在投了赞成票
    • 没有问题。很高兴知道答案对您有所帮助。
    【解决方案3】:

    在您的清单中,在您的 Activity 部分下,试试这个:

    <activity>            
         android:launchMode="singleTask"
    </activity>
    

    如果您希望您的Activity不要出现在您最近的应用列表中,请尝试

    <activity>            
        android:excludeFromRecents="true"
    </activity>
    

    希望这会有所帮助。

    【讨论】:

    • 我希望我的应用显示在最近的应用列表中。 launchMode="singleTask" 不起作用
    【解决方案4】:

    当您按下 OK 按钮时,您 finish() 活动并从历史记录中再次选择它显然会重新创建它。

    你应该做的是使用android:excludeFromRecents="true"从历史/最近隐藏这个警报活动

    并将launchMode = "singleInstance" 与此一起使用,这样 android 就永远无法同时创建此活动的另外两个实例。

    【讨论】:

      【解决方案5】:

      您可以通过在启动 Activity 的 Intent 中添加标志来避免这个问题:

      Intent i = new Intent();
      i.setClass(this, PopUpActivity.class);
      i.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
      startActivity(i);
      

      设置Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS 将使您的 PopupActivity 在最近的任务中不可见。

      【讨论】:

        猜你喜欢
        • 2015-01-31
        • 1970-01-01
        • 1970-01-01
        • 2012-08-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多