如何在安卓设备上保存并“重播”通知?

huangapple go评论70阅读模式
英文:

How to save and "replay" a notification on Android?

问题

在底部进行了更新并解释了原因,但仍然没有修复

我试图捕获一条通知,并在稍后在我关闭它后重新播放它。从我到目前为止已经找出的内容来看,我可以捕获一条通知,但是当我尝试使用NotificationManager.notify()创建一条新的通知时,什么都没有发生。没有错误,什么都没有。我应该能做到这一点吗?

也许我没有采取正确的方法,有人可以提出更好的方法建议。如上所述,我希望能够知道用户何时收到通知,并完整地捕获通知,因此即使在通知被解除时,我也可以将其恢复。也许有一种方法可以从通知历史记录中恢复事物,但我还没有完全弄清楚它的工作原理。以下是我目前的代码。我可以成功地侦听通知何时被发布或移除。目标是在通知发布时发送广播,其中包含通知的id和实际的通知本身(我认为这部分是有效的),以及当按下按钮时重新创建通知。当我按下按钮时,什么都没有发生。

public class MainActivity extends AppCompatActivity {

    // ... (其他部分略)

    final Button button = findViewById(R.id.button);
    button.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            Bundle extras = myNotify.extras;
            String title = extras.getString("android.title");
            String text = extras.getString("android.text");
            NotificationManager nManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
            nManager.notify(notification_id, myNotify);
        }
    });

    // ... (其他部分略)
}
public class MyBroadcastReceiver extends BroadcastReceiver {

    @Override
    @Nullable
    public void onReceive(Context context, Intent intent) {
        // 这里是你接收到的广播
        // 如果你在意图中添加了额外的信息,在这里也可以获取到
        // 这需要一些空值检查
        Bundle b = intent.getExtras();
        notification_id = b.getInt("notification_id");
        myNotify = b.getParcelable("notification");
    }
}
public class MyNotificationListenerService extends NotificationListenerService {

    // ... (其他部分略)

    @Override
    public void onNotificationPosted(StatusBarNotification sbn) {
        if ((sbn.getNotification().flags & Notification.FLAG_GROUP_SUMMARY) != 0) {
            // 忽略分组摘要通知
            return;
        }
        notification_id = sbn.getId();
        myNotify = sbn.getNotification();

        Intent intent = new Intent("notification_restore");
        Bundle b = new Bundle();
        b.putInt("notification_id", notification_id);
        b.putParcelable("notification", myNotify);
        intent.putExtras(b);
        LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
    }

    // ... (其他部分略)
}

编辑:

所以看起来我的通知没有显示的原因是因为它抱怨找不到一个通道,尽管我尝试重新播放的通知有一个通道。精确的错误是:

E/NotificationService: No Channel found for pkg=com.gevdev.notify, channelId=bugle_default_channel, id=0, tag=null, opPkg=com.gevdev.notify, callingUid=10086, userId=0, incomingUserId=0, notificationUid=10086, notification=Notification(channel=bugle_default_channel pri=1 contentView=null vibrate=null sound=null tick defaults=0x0 flags=0x10 color=0xff2a56c6 category=msg groupKey=bugle_notification_group_key sortKey=00 actions=2 vis=PRIVATE)

我仍然是 Android 的新手,但我最初的猜测是找到的 bugle_default_channel 通道在我的包名下没有找到,但我还不知道如何修复这个问题。

英文:

Edit with an update at the bottom with the cause, but still no fix

I am trying to capture a notification and later replay it once I dismiss it. From what I've been able to figure out so far, I can capture a notification, but when I try create a new notification using NotificationManager.notify(), nothing happens. No errors, nothing. Is this even something I should be able to do?

Maybe I am not taking the right approach and someone can suggest a better approach. Like I stated above, I want to be able to know when a user receives a notification and to capture the notification in its entirety, so even when it's dismissed, I can restore it. Maybe there is a way to restore things from the notification history but I haven't been able to figure out fully how that works yet. Here's the code I have so far. I can successfully listen to when a notification is posted or removed. The goal is to send a broadcast when a notification is posted with the notification id and the actual Notification itself (this part works I think), and when the button is pressed, recreate the notification. When I press the button, nothing happens.

public class MainActivity extends AppCompatActivity {

    private int notification_id = -1;
    private Notification myNotify;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main3);

        final Button button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                Bundle extras = myNotify.extras;
                String title = extras.getString("android.title");
                String text = extras.getString("android.text");
                NotificationManager nManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
                nManager.notify(notification_id, myNotify);
            }
        });
    }


    private MyBroadcastReceiver myReceiver;

    @Override
    public void onResume() {
        super.onResume();
        myReceiver = new MyBroadcastReceiver();
        final IntentFilter intentFilter = new IntentFilter("notification_restore");
        LocalBroadcastManager.getInstance(this).registerReceiver(myReceiver, intentFilter);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (myReceiver != null)
            LocalBroadcastManager.getInstance(this).unregisterReceiver(myReceiver);
        myReceiver = null;
    }

    public class MyBroadcastReceiver extends BroadcastReceiver {

        @Override
        @Nullable
        public void onReceive(Context context, Intent intent) {
            // Here you have the received broadcast
            // And if you added extras to the intent get them here too
            // this needs some null checks
            Bundle b = intent.getExtras();
            notification_id = b.getInt("notification_id");
            myNotify = b.getParcelable("notification");
        }
    }

}
public class MyNotificationListenerService extends NotificationListenerService {

    private int notification_id;
    private Notification myNotify;

    @Override
    public void onNotificationPosted(StatusBarNotification sbn) {
        if ((sbn.getNotification().flags & Notification.FLAG_GROUP_SUMMARY) != 0) {
            //Ignore the notification
            return;
        }
        notification_id = sbn.getId();
        myNotify = sbn.getNotification();

        Intent intent = new Intent("notification_restore");
        Bundle b = new Bundle();
        b.putInt("notification_id", notification_id);
        b.putParcelable("notification", myNotify);
        intent.putExtras(b);
        LocalBroadcastManager.getInstance(this).sendBroadcast(intent);

    }

    @Override
    public void onNotificationRemoved(StatusBarNotification sbn) {
        if ((sbn.getNotification().flags & Notification.FLAG_GROUP_SUMMARY) != 0) {
            //Ignore the notification
            return;
        }
    }
}

Edit:

So it looks like the reason my notification isn't showing up is because it complains about not finding a channel, even though the notification I am trying to replay has one. The exact error is:

E/NotificationService: No Channel found for pkg=com.gevdev.notify, channelId=bugle_default_channel, id=0, tag=null, opPkg=com.gevdev.notify, callingUid=10086, userId=0, incomingUserId=0, notificationUid=10086, notification=Notification(channel=bugle_default_channel pri=1 contentView=null vibrate=null sound=null tick defaults=0x0 flags=0x10 color=0xff2a56c6 category=msg groupKey=bugle_notification_group_key sortKey=00 actions=2 vis=PRIVATE)

I am still new to android, but my initial guess is that the channelId found bugle_default_channel isn't found under my package name, but I don't know how to fix this yet.

答案1

得分: 0

已解决

尽管我要重新发送的通知具有频道ID,但是NotificationManager并没有注册该通知频道。我根据此处找到的代码进行了解决。以下是注册方法。

if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
    NotificationChannel notificationChannel = nManager.getNotificationChannel(myNotify.getChannelId());
    if (notificationChannel == null) {
        int importance = NotificationManager.IMPORTANCE_HIGH;
        notificationChannel = new NotificationChannel(myNotify.getChannelId(), "在此添加描述", importance);
        notificationChannel.setLightColor(Color.GREEN);
        notificationChannel.enableVibration(true);
        nManager.createNotificationChannel(notificationChannel);
    }
}
英文:

Figured it out

Even though the notification that I am grabbing to replay has a channel ID, the NotificationManager doesn't have that notification channel registered. I figured it based off the code found here. This is how to register it.

                if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
                    NotificationChannel notificationChannel = nManager.getNotificationChannel(myNotify.getChannelId());
                    if (notificationChannel == null) {
                        int importance = NotificationManager.IMPORTANCE_HIGH;
                        notificationChannel = new NotificationChannel(myNotify.getChannelId(), "Description Goes Here", importance);
                        notificationChannel.setLightColor(Color.GREEN);
                        notificationChannel.enableVibration(true);
                        nManager.createNotificationChannel(notificationChannel);\
                    }
                }

huangapple
  • 本文由 发表于 2020年10月24日 11:00:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/64509546.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定