9

I've implemented a class that extends NotificationListenerService which works fine for picking up on notifications posted.

I'm then wanting to take the statusBarNotification object received and broadcast it.

I'd doing the following:

@Override
public void onNotificationPosted(StatusBarNotification statusBarNotification) {

    Intent intent = new Intent();
    intent.putExtra("STATUS_BAR_NOTIFICATION",statusBarNotification);
    intent.setAction("com.example.NotificationPosted");
    sendBroadcast(intent);
}

But when I do this I get the following error:

01-05 01:50:14.333  19574-19673/com.example W/NotificationListenerService[NotificationListener]﹕ Error running onNotificationPosted
java.lang.RuntimeException: Not allowed to write file descriptors here
        at android.os.Parcel.nativeAppendFrom(Native Method)
        at android.os.Parcel.appendFrom(Parcel.java:431)
        at android.os.Bundle.writeToParcel(Bundle.java:1679)
        at android.os.Parcel.writeBundle(Parcel.java:636)
        at android.app.Notification.writeToParcel(Notification.java:962)
        at android.service.notification.StatusBarNotification.writeToParcel(StatusBarNotification.java:106)
        at android.os.Parcel.writeParcelable(Parcel.java:1285)
        at android.os.Parcel.writeValue(Parcel.java:1204)
        at android.os.Parcel.writeArrayMapInternal(Parcel.java:618)
        at android.os.Bundle.writeToParcel(Bundle.java:1692)
        at android.os.Parcel.writeBundle(Parcel.java:636)
        at android.content.Intent.writeToParcel(Intent.java:7013)
        at android.app.ActivityManagerProxy.broadcastIntent(ActivityManagerNative.java:2361)
        at android.app.ContextImpl.sendBroadcast(ContextImpl.java:1127)
        at android.content.ContextWrapper.sendBroadcast(ContextWrapper.java:365)
        at com.example.NotificationListener.onNotificationPosted(NotificationListener.java:113)
        at android.service.notification.NotificationListenerService$INotificationListenerWrapper.onNotificationPosted(NotificationListenerService.java:168)
        at android.service.notification.INotificationListener$Stub.onTransact(INotificationListener.java:56)
        at android.os.Binder.execTransact(Binder.java:404)
        at dalvik.system.NativeStart.run(Native Method)

Can anyone see what I'm doing wrong, or is this not possible. StatusBarNotification implements Parcelable

Andrew
  • 7,548
  • 7
  • 50
  • 72
  • Have you seen [this](http://stackoverflow.com/questions/18706062/android-exception-with-sending-parcelfiledescriptor-via-intent#comment27633853_18706062) comment? Granted, it's not an actual answer, but he may be onto something. – A--C Jan 05 '14 at 02:12
  • 1
    After a little more experimenting, some notifications work, whereas others don't. Google keep notification and a few others but things like Facebook messenger don't. As it's an Android class that's parcelable I can only think it's a bug in Android. – Andrew Jan 05 '14 at 09:36

4 Answers4

2

I've had the same problem with notifications from Twitter. I successfully solved it setting the notification's extras to null.

Try this:

@Override
@SuppressLint("NewApi") // Notification.extras is only available in API Level 19+
public void onNotificationPosted(StatusBarNotification statusBarNotification) {

    // Apprarently, the bug is caused by the extras when they're written to the parcel
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
         statusBarNotification.getNotification().extras = null;
    }
    Intent intent = new Intent();
    intent.putExtra("STATUS_BAR_NOTIFICATION",statusBarNotification);
    intent.setAction("com.example.NotificationPosted");
    sendBroadcast(intent);
}

Please note that this solution could break the functionality of notification's app if you send the contentIntent (the app could think the extras are there without checking).

Twinone
  • 2,949
  • 4
  • 28
  • 39
  • In kitkat, setting the extras to null is going to nullify any and all benefits it has. Having a bundle makes it convenient... – Mgamerz May 20 '14 at 05:20
0

This is probably some kind of android bug as some users noted above. If you want to get around it and still use as much bundle as possible consider implementing custom bundle serializer/deserializer. I already answered a question how to build such thing in How to serialize a Bundle? and what is missing is how to actually use it when packing/unpacking the parcel. This is described here:

@Override public void writeToParcel(Parcel dest, int flags) {
    byte[] bytes = serializeBundle(yourBundle);
    dest.writeInt(bytes.length);
    dest.writeByteArray(bytes);
}

and then

    YourConstructor(Parcel in) {
         byte[] bytes = new byte[in.readInt()]; // read the length of the array
         in.readByteArray(bytes); // read bytes to array 
         yourBundle = deserializeBundle(bytes); // unpack the bundle
    }
Community
  • 1
  • 1
vanomart
  • 1,739
  • 1
  • 18
  • 39
0

I have crash only kitkat(api 19). Му error(show all error scrooling to right):

Error running onNotificationPosted
                                                                                                                    java.lang.AbstractMethodError: abstract method not implemented
                                                                                                                          at android.service.notification.NotificationListenerService.onNotificationPosted(NotificationListenerService.java)
                                                                                                                          at service.CustomNotificationListenerService.onNotificationPosted(CustomNotificationListenerService.kt:46)
                                                                                                                          at android.service.notification.NotificationListenerService$INotificationListenerWrapper.onNotificationPosted(NotificationListenerService.java:168)
                                                                                                                          at android.service.notification.INotificationListener$Stub.onTransact(INotificationListener.java:56)
                                                                                                                          at android.os.Binder.execTransact(Binder.java:404)                                                                                                                     at dalvik.system.NativeStart.run(Native Method)

Simple Solve: i removed method: super()

Fortran
  • 2,218
  • 2
  • 27
  • 33
0

This solution worked for me:

@Override
public void onNotificationPosted(StatusBarNotification statusBarNotification) {

Bundle bundle = new Bundle(); statusBarNotification.getNotification().extras.putBundle("android.car.EXTENSIONS", bundle);

Intent intent = new Intent();
intent.putExtra("STATUS_BAR_NOTIFICATION",statusBarNotification);
intent.setAction("com.example.NotificationPosted");
sendBroadcast(intent);

}