4

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

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

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

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 将被调用。”。我怎样才能做到这一点?

4

2 回答 2

2

除了持有启动活动的意图外,PendingIntent还可以持有“发射”广播的意图

您可以使用此类自定义广播作为通知的触发器,然后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 whenonCreate()调用,然后取消注册onDestroy()

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

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

于 2013-01-24T11:17:29.680 回答
1

让我首先尝试将您的问题转换为另一个问题(只是为了清楚起见):如何让我的 Activity 在暂停之前执行代码,因为将显示与我的通知(我可以控制)关联的 Activity?

前提是翻译足够好,可以回答:

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

因此,对于一个合适的答案,我相信人们必须跳出框框思考一下,这取决于您打算执行的代码的性质和执行它的动机。

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

问题更新后更新:

您可以避免在用户按下通知时触发下一个 Activity,而只需触发一个事件。如果你的activity以编程方式注册了一个BroadcastReceiver,它应该能够接收到这个事件,然后按照你的意愿更新自己并启动下一个Activity。

于 2013-01-24T09:43:28.683 回答