如何检测您的活动是否因为您创建的PendingIntent而被暂停?

时间:2013-01-04 14:48:18

标签: android android-pendingintent activity-lifecycle

如果我有一个位于前台的活动并导航到我的应用程序中的另一个活动,我可以通过在开始转移时设置标记并在转移到新活动时擦除它来检测到这一点。这允许我区分由于内部(标志设置)或外部(标志未设置)事件导致的活动onPause。

但是,我在为Notifications中嵌入的PendingIntents执行此操作时遇到了麻烦。是否可以检测到我的Activity正在onPaused,因为他们选择了我在通知栏上创建的通知?我可以使用某种通知监听器,它会在强烈触发通知之前触发并执行挂起的意图吗?onPauses my Activity?

我很欣赏这有点令人困惑,所以我做了一个骨架项目来证明这个问题:

package com.example.notificationtest;

import android.os.Bundle;
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.view.View;

public class MainActivity extends Activity {

private static final int INCOMING_NOTIFICATION_ID = 1;
private static final String TAG = "NotificationTest";

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
}

@Override
public void onPause() {
    super.onPause();
    Log.e(TAG,"onPause");
}

@Override
public void onResume() {
    super.onResume();
    Log.e(TAG,"onResume");
}

public void onTransitionButtonClick(View view) {
    Intent intent = new Intent(this, MainActivity.class);
    Log.e(TAG,"About to start activity: onPause will be invoked.");
    startActivity(intent);
}

public void onNotificationButtonClick(View view) {
    Intent intent = new Intent(this, MainActivity.class); 
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
    Notification notification = new Notification(android.R.drawable.alert_dark_frame, "Alert!", System.currentTimeMillis());
    notification.defaults |= Notification.DEFAULT_SOUND;
    notification.defaults |= Notification.DEFAULT_VIBRATE;
    notification.defaults |= Notification.DEFAULT_LIGHTS;
    notification.flags |= Notification.FLAG_AUTO_CANCEL;
    notification.flags |= Notification.FLAG_INSISTENT;
    notification.setLatestEventInfo(this, "Click to open", "Click to open", pendingIntent);

    // Show the alert.
    final NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
    notificationManager.notify(INCOMING_NOTIFICATION_ID, notification);
}

}

使用activity_main.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<Button
    android:id="@+id/notify_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:padding="@dimen/padding_medium"
    android:text="Make a notification"
    android:onClick="onNotificationButtonClick"
    tools:context=".MainActivity" />

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_toRightOf="@id/notify_button"
    android:padding="@dimen/padding_medium"
    android:text="Normal transition"
    android:onClick="onTransitionButtonClick"
    tools:context=".MainActivity" />

</RelativeLayout>

如果选择“正常转换”按钮,日志将显示“关于启动活动:将调用onPause”。在onPause之前。

如果您选择“发出通知”按钮,然后向下拖动通知栏并点按通知,我希望在onPause之前收到该点按,这样我就可以插入相同的行“即将开始活动:将调用onPause。“我怎么能这样做?

2 个答案:

答案 0 :(得分:2)

除了持有开始活动的意图之外, PendingIntent也可以持有&#34; fire&#34;广播

您可以使用此类自定义广播作为通知的触发器,然后实施将注册到该广播的BroadcastReceiver,并显示您想要的任何内容,然后才会启动所需的活动。

Intent intent = new Intent("my.custom.broadcast.action");
pendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);

接收器看起来像这样:

private BroadcastReceiver mReceiver = new BroadcastReceiver() {

    @Override
    public void onReceive(Context context, Intent intent) {
        //do whatever you want
        // if this code is being executed - it's a sign that the user clicked on the notification...

        Intent intent = new Intent(this, MainActivity.class);
        Log.e(TAG,"About to start activity: onPause will be invoked.");
        startActivity(intent);

    }
};

忘记在mReceiver调用时注册onCreate(),并取消注册onDestroy()

registerReceiver(mReceiver , new IntentFilter("my.custom.broadcast.action"));
unregisterReceiver(mReceiver);

在这种方法中,您可以准确控制用户单击通知时会发生什么。正如您所看到的 - 只有在点击通知时才可以发送广播。没有人说你必须开始活动..

答案 1 :(得分:1)

让我首先尝试将您的问题转换为另一个问题(仅为了清晰起见):如果我的活动执行代码暂停之前我怎么能执行代码,因为与我的通知相关联的活动(我可以控制)正在进行要显示?

如果翻译足够好以便回答:

您确定这种方法是一种解决方案吗?因为很多情况下您的活动将暂停,并且用户“几乎立即”之后会显示您的通知活动,而中间仍会有步骤(就像首先查看其他通知时一样)。我认为从技术上讲,这意味着您仍然必须在那里执行相同的代码,同时您无法表明您的通知将在“不久的将来”被查看。

因此,对于一个合适的答案,我相信一个人必须在盒子外面思考一下,这取决于你打算执行的代码的性质和它的动机。

因此,如果您在这方面更新您的问题并通知我,我将很高兴再看看。

更新问题后更新:

当用户按下通知时,您可以避免触发下一个Activity,而只是触发事件。如果您的活动以编程方式注册BroadcastReceiver,它应该能够接收此事件,然后更新自己并按照您的意愿开始下一个Activity。