Reputation: 1644
I'm writing an android app that tracks the user's location and shows the distance, time and price of the trip in a notification, all this tracked in a ForegroundService
. The service tracks the location, price and the time, and I'm updating the notification every second.
I get this TransactionTooLargeException
in production for the very first notification update, it only happens on Samsung devices running Android 8.0+.
This is what's happening:
I call the start
method from the service:
public void start(MeasureService service) {
service.startForeground(NOTIFICATION_ID, getNotification(0, 0, 0));
}
I call the update
method from the service:
public void update(int price, float meters, long time) {
mNotificationManager.notify(NOTIFICATION_ID, getNotification(price, meters, time));
}
Actually, these calls are called right after one another, the crash is coming from the update
method. Can this (calling them one after the other) be a problem?
this is the getNotification
:
private Notification getNotification(int price, float meters, long seconds) {
if (mNotificationBuilder == null) {
createNotificationBuilder();
}
return mNotificationBuilder
.setCustomContentView(getSmallView(price))
.setCustomBigContentView(getBigView(price, seconds, meters))
.build();
}
where the getSmallView
and getBigView
methods are like this:
private RemoteViews getSmallView(int price) {
String priceText = ...;
mSmallView.setTextViewText(R.id.price, priceText);
return mSmallView;
}
private RemoteViews getBigView(int price, long seconds, float meters) {
String priceText = ...;
String timeText = ...;
String distanceText = ...;
mBigView.setTextViewText(R.id.price, priceText);
mBigView.setTextViewText(R.id.time, timeText);
mBigView.setTextViewText(R.id.distance, distanceText);
return mBigView;
}
and this is how I create the notificationBuilder
:
private void createNotificationBuilder() {
NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_LOW);
((NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE)).createNotificationChannel(channel);
mNotificationBuilder = new NotificationCompat.Builder(mContext, NOTIFICATION_CHANNEL_ID);
mNotificationBuilder = mNotificationBuilder
.setSmallIcon(R.drawable.icon)
.setOngoing(true)
.setContentIntent(getOpenMeasurePageIntent());
}
and the getOpenMeasurePageIntent
:
private PendingIntent getOpenMeasurePageIntent() {
Intent launchMeasureIntent = new Intent(mContext, MainActivity.class);
launchMeasureIntent.setAction(...);
launchMeasureIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
return PendingIntent.getActivity(mContext, 0, launchMeasureIntent, 0);
}
This is the crash log I get:
Caused by: java.lang.RuntimeException: android.os.TransactionTooLargeException: data parcel size 560988 bytes
16 at android.app.NotificationManager.notifyAsUser(NotificationManager.java:319)
17 at android.app.NotificationManager.notify(NotificationManager.java:284)
18 at android.app.NotificationManager.notify(NotificationManager.java:268)
19 at com.myapp.service.measure.MyNotification.void update(int,float,long) <- this is called from the timer
I found a lot of similar issues online, but they are usually about passing big chunks of data in the intent, which I believe I'm not doing.
Any idea what I might be doing wrong?
Upvotes: 7
Views: 1114
Reputation: 3
I had the same problem and required updating the notification every second with RemoteViews
. The catch is when you use RemoteViews
, do not reuse the previously initiated one.
When you update the previous ones, there will be some memory leak every time you update and finally at one point the instance becomes so large that it causes the exception.
So, just initiate new RemoteViews instance everytime you update the notification.
Upvotes: 0
Reputation: 429
Ran into the same issue on Android 13 (LineageOS 20).
Ended up acquiring about 900 notifications in KDEConnect alone, which ended up preventing the phone from receiving phone calls (they would receive, but not even wake the phone up, no way to accept them as no notification would pop up), Clock alarms wouldn't trigger other than play the sound, and notifications from all other apps wouldn't arrive.
Simply swiping the KDEConnect tile froze the phone for about 10 seconds and everything resumed as normal.
Generating hundreds of notifications still looks like a no go and if you are getting this while developing, it's probably worth trying to clear the existing notifications.
Getting the notification amount through adb
and bash
:
$ adb shell dumpsys notification | grep NotificationRecord | wc -l
937
Logcat from A13:
E NotificationAssistants: unable to notify assistant (enqueued): android.service.notification.INotificationListener$Stub$Proxy@16acbc
E NotificationAssistants: android.os.TransactionTooLargeException: data parcel size 535556 bytes
E NotificationAssistants: at android.os.BinderProxy.transactNative(Native Method)
E NotificationAssistants: at android.os.BinderProxy.transact(BinderProxy.java:584)
E NotificationAssistants: at android.service.notification.INotificationListener$Stub$Proxy.onNotificationEnqueuedWithChannel(INotificationListener.java:599)
E NotificationAssistants: at com.android.server.notification.NotificationManagerService$NotificationAssistants.onNotificationEnqueuedLocked(NotificationManagerService.java:10477)
E NotificationAssistants: at com.android.server.notification.NotificationManagerService$NotificationAssistants.-$$Nest$monNotificationEnqueuedLocked(Unknown Source:0)
E NotificationAssistants: at com.android.server.notification.NotificationManagerService$EnqueueNotificationRunnable.run(NotificationManagerService.java:7543)
E NotificationAssistants: at android.os.Handler.handleCallback(Handler.java:942)
E NotificationAssistants: at android.os.Handler.dispatchMessage(Handler.java:99)
E NotificationAssistants: at android.os.Looper.loopOnce(Looper.java:201)
E NotificationAssistants: at android.os.Looper.loop(Looper.java:288)
E NotificationAssistants: at com.android.server.SystemServer.run(SystemServer.java:965)
E NotificationAssistants: at com.android.server.SystemServer.main(SystemServer.java:650)
E NotificationAssistants: at java.lang.reflect.Method.invoke(Native Method)
E NotificationAssistants: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
E NotificationAssistants: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:914)
Upvotes: 1
Reputation: 3936
i think problem is in updating Notification every seconds.
Solution
i suggest you should update notification only when data likes(distance, price) changed.
Upvotes: 0