前言
最近在写一个点击通知发出Broadcast
并在Broadcast Receiver
中处理一些事情后再打开Activity
的功能。调试时没有问题,但在应用打包后点击通知时Activity
无法被打开。在Logcat
中可以看到以下调试信息:Indirect notification activity start (trampoline) from xx blocked
关于问题
经过测试发现:已成功触发广播接收器的onReceive
方法,问题出在无法在点击通知时间接地
打开Activity
。
查阅了相关资料,以Android 12
为目标平台的应用有一些行为变更。其中,限制通知 trampoline 导致无法间接地打开Activity
。
通知 trampoline:当用户与通知互动时,某些应用会启动一个应用组件(如
Broadcast
)来响应通知点按操作,该应用组件最终会启动用户最终看到并与之互动的 activity。此应用组件被称为通知 trampoline。
如何解决
思路
我建立了一个用户感知不到的Activity
,在点击通知时直接打开这个跳板Activity
。在跳板Activity
的onCreate
方法中处理数据、发送广播、启动服务等,最后启动想要打开的Activity
。进行完以上所有操作后,调用finish
方法结束这个跳板Activity
实现
- 新建一个空的
Activity
(不要勾选Generate a Layout File
)
- 在
AndroidManifest.xml
中对Activity
进行配置
<activity
android:name=".TrampolineActivity"
android:excludeFromRecents="true"
android:exported="false"
android:theme="@android:style/Theme.Translucent.NoTitleBar"
android:label="TrampolineActivity" />
- 在
TrampolineActivity
中编写业务代码
package xxx;
import static xxx.NOTIFICATION_PRESS_ACTION;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
public class TrampolineActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 编写你的代码,发送 Broadcast 等
Intent mainActivityIntent = new Intent(this, MainActivity.class);
mainActivityIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(mainActivityIntent); // 启动要打开的Activity
finish(); // 结束跳板Activity
}
}
- 设置
Notification
的ContentIntent
Intent intent = new Intent(context, TrampolineActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, gatheringEventItem.getId(), intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
Notification notification = new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID)
.setContentTitle("通知标题")
.setContentText("通知内容")
.setContentIntent(pendingIntent)
.setAutoCancel(true)
.build();