如何修复:android.app.RemoteServiceException:从包*发布的错误通知:无法创建图标:StatusBarIcon

Fis*_*tix 112 android android-notifications android-resources android-drawable

我在崩溃日志中看到以下异常:

android.app.RemoteServiceException: Bad notification posted from package com.my.package: Couldn't create icon: StatusBarIcon(pkg=com.my.package user=0 id=0x7f02015d level=0 visible=true num=0 )
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1456)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:146)
    at android.app.ActivityThread.main(ActivityThread.java:5487)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
    at dalvik.system.NativeStart.main(Native Method)
Run Code Online (Sandbox Code Playgroud)

我使用以下方法通过AlarmManager从PendingIntent集中从IntentService发布我的通知.此处传递的所有值都来自PendingIntent/IntentService中的bundle extras.

/**
 * Notification 
 *
 * @param c
 * @param intent
 * @param notificationId
 * @param title
 * @param message
 * @param largeIcon
 * @param smallIcon
 */
public static void showNotification(Context c, Intent intent,
        int notificationId, String title, String message, int largeIcon,
        int smallIcon) {
    PendingIntent detailsIntent = PendingIntent.getActivity(c,
            notificationId, intent, PendingIntent.FLAG_UPDATE_CURRENT);

    // BUILD
    NotificationCompat.Builder mNotifyBuilder = new NotificationCompat.Builder(
            c);
    // TITLE
    mNotifyBuilder.setContentTitle(title).setContentText(message);

    // ICONS
    mNotifyBuilder.setSmallIcon(smallIcon);
    if (Util.isAndroidOSAtLeast(Build.VERSION_CODES.HONEYCOMB)) {
        Bitmap large_icon_bmp = ((BitmapDrawable) c.getResources()
                .getDrawable(largeIcon)).getBitmap();
        mNotifyBuilder.setLargeIcon(large_icon_bmp);
    }

    mNotifyBuilder.setContentIntent(detailsIntent);
    mNotifyBuilder.setVibrate(new long[] { 500, 1500 });
    mNotifyBuilder.setTicker(message);
    mNotifyBuilder.setContentText(message);

    // NOTIFY
    NotificationManager nm = (NotificationManager) c
            .getSystemService(Context.NOTIFICATION_SERVICE);
    nm.notify(notificationId, mNotifyBuilder.build());
}
Run Code Online (Sandbox Code Playgroud)

从我所看到的其他答案 - 我看到的异常发生时setSmallIcon()没有被正确调用.

我已检查并仔细检查传递的资源ID是否正确.

Fis*_*tix 94

发生的事情是,我在PendingIntent包中包含了对图标的整数引用,并且该整数稍后在发布到NotificationManager时被引用.

在获取整数引用和待处理的意图之间,应用程序已更新并且所有可绘制引用都已更改.用于引用正确drawable的整数现在引用了不正确的drawable或者根本没有引用(根本没有 - 导致此崩溃)

  • 离奇.换句话说,这是不可修复的呢?我在我的应用程序中看到了同样的崩溃. (4认同)
  • 如果你想引用R.drawable.my_image,将它作为字符串保存为bundle(`bundle.putString("img","my_image")`更安全,然后在需要时转换为实际的@DrawableRes整数,如下所示: `ctx.resources.getIdentifier(bundle.getString("img"),"drawable",ctx.packageName)` (3认同)
  • 当应用程序被杀死以进行更新时,是否可以清除通知和相关的所有内容?(假设这将使应用程序避免该问题) (2认同)

Bub*_*vor 47

VectorXml已知在您的通知中使用会导致此问题.使用png

  • 只使用了PNG. (2认同)

ben*_*daf 25

每当我想在Kitkat上发布通知时,我都会遇到同样的问题.导致这个问题的原因是我已经定义了xml中的每个图标(来自svg),小图标和动作图标.在我用png-s替换它们后,问题在我身边解决了.

  • 我可以证实.通知中的矢量drawable导致KitKat上的RemoteServiceException. (3认同)
  • 在KitKat的情况下,当我用PNG替换XML时问题得到解决:new NotificationCompat.Builder(context,CHANNEL_ID).setSmallIcon(R.drawable.my_icon) (2认同)

Kon*_*esh 9

android.app.RemoteServiceException:发布错误通知

我有同样的问题,但我得到了解决.我的问题是远程视图的".xml文件".

在我的xml文件中,我ViewLinearLayoutfor divider 之间添加了一个.

<View
    android:layout_width="match_parent"
    android:layout_height="1dp"
    android:id="@+id/view"
    android:background="#000000" />
Run Code Online (Sandbox Code Playgroud)

上面的View组件创建了Bad通知异常.此例外原因仅是Remoteviews的xml文件.

删除该View组件后,我的代码正确执行,没有任何异常.所以我觉得通知抽屉不接受任何自定义视图.

因此,您不会在RemoteView对象的.xml文件中绘制任何类似上述视图的内容.


thu*_*ick 6

在我的应用程序中,这种错误仅在升级期间发生.如果资源ID在较新版本中发生更改,则Android RemoteView可能无法找到该资源并将其丢弃RemoteServiceException.如果您发布第3版并且不更改资源ID,则错误可能只是暂时消失.

可以通过编辑res/values/public.xml和减少这种错误res/values/ids.xml.如果资源ID不在public.xml或,则编译器将生成单独的资源ID ids.xml.当您更改资源名称或添加一些新资源时,ID可能会更改,某些设备可能无法找到它.

所以步骤如下:

  1. 反编译apk文件并res/values找到public.xmlids.xml
  2. 在您的应用中查找与RemoteView相关的所有资源并复制它们(字符串,尺寸,可绘制,布局,ID,颜色......)
  3. 创建public.xmlids.xmlres/values你的源代码,并粘贴你刚刚复制的行

注意:

Gradle 1.3.0及以上版本忽略了本地版本public.xml.为了使它工作,你需要添加一些脚本build.gradle

afterEvaluate {
    for (variant in android.applicationVariants) {
        def scope = variant.getVariantData().getScope()
        String mergeTaskName = scope.getMergeResourcesTask().name
        def mergeTask = tasks.getByName(mergeTaskName)
        mergeTask.doLast {
            copy {
                int i=0
                from(android.sourceSets.main.res.srcDirs) {
                    include 'values/public.xml'
                    rename 'public.xml', (i == 0? "public.xml": "public_${i}.xml")
                    i++
                }
                into(mergeTask.outputDir)
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

注意:此脚本不支持子模块项目.我正在努力解决它.


Car*_*iel 6

我的问题是我使用的图标

.setSmallIcon(R.drawable.ic_stat_push_notif)
Run Code Online (Sandbox Code Playgroud)

没有相应地生成。根据官方文件

如提供特定于密度的图标集和支持多个屏幕中所述,您应该为所有通用的屏幕密度(包括低,中,高和超高密度屏幕)创建单独的图标。这样可以确保您的图标将在可以安装应用程序的一系列设备上正确显示。

因此,满足上述要求的最佳方法是使用Roman Nurik在https://romannurik.github.io/AndroidAssetStudio/index.html上提供的Notification Generator

这样,您可以使用图像(考虑到该背景必须具有透明背景),并让生成器为您生成通知图标的不同大小的工作。

最重要的是,如果浏览图像后使用的图标生成器显示白色填充的圆形或正方形,则图像存在问题,可能是因为它没有任何透明性,因此请确保你有这个确定。

  • 就我而言,我在`drawable` 文件夹中有vector,在`drawable-hdpi`、`xhdpi` 等中有png。但是`drawable-mdpi` 没有png,并且在发布通知时它在MDPI 设备上崩溃了。 (2认同)

Hai*_*lik 6

在Android Studio 3.0.0及更高版本中,在drawables文件夹中添加新图像时,选择drawable而不是drawable-v24。在此输入图像描述

如果您正在使用的图像已经是 (v24),只需将其复制并粘贴到同一目录中(例如,drawables)。这次它会询问您是常规版本还是 v24 - 只需确保它不是 v24,然后重试一次,这应该可以修复错误。


Ash*_*ani 5

以防万一图标不重要,您可以替换,

R.drawable.your_icon
Run Code Online (Sandbox Code Playgroud)

android.R.drawable.some_standard_icon
Run Code Online (Sandbox Code Playgroud)

这有效!


Gla*_*cus 5

如果您在更新应用程序时看到通知,则可能会遇到这种情况。您可能需要做的是创建一个等待 PACKAGE_CHANGED 消息的 BroadcastReceiver,此时您关闭所有服务,这也将消除其关联的通知。

 <receiver android:name=".MyBroadcastReceiver">
    <intent-filter>
        <action android:name="android.intent.action.PACKAGE_CHANGED" />
    </intent-filter>
</receiver>
Run Code Online (Sandbox Code Playgroud)