Android 11 MediaStyle 通知崩溃

问题描述 投票:0回答:2

我在我的应用程序中使用 MediaStyle 通知。在 Android 11 之前,它一直工作正常。在 Android 11 上,它会导致 Android UI 崩溃(不仅仅是应用程序,还会崩溃 Android 的 UI)。

应用程序上的logcat没有错误,但Android本身有错误。

    fun buildNotificationAsync(sessionToken: MediaSessionCompat.Token): Deferred<Notification> = GlobalScope.async {
    if (shouldCreateNowPlayingChannel()) {
        createNowPlayingChannel()
    }

    val controller = MediaControllerCompat(context, sessionToken)
    val description = controller.metadata.description
    val playbackState = controller.playbackState

    val builder = NotificationCompat.Builder(context, NOW_PLAYING_CHANNEL)

    // Only add actions for skip back, play/pause, skip forward, based on what's enabled.
    var playPauseIndex = 0
    if (playbackState.isSkipToPreviousEnabled) {
        builder.addAction(skipToPreviousAction)
        ++playPauseIndex
    }
    if (playbackState.isRewindEnabled) {
        builder.addAction(rewindAction)
        ++playPauseIndex
    }

    if (playbackState.isPlaying) {
        builder.addAction(pauseAction)
    } else if (playbackState.isPlayEnabled) {
        builder.addAction(playAction)
    }
    if (playbackState.isFastForwardEnabled) {
        builder.addAction(fastForwardAction)
    }
    if (playbackState.isSkipToNextEnabled) {
        builder.addAction(skipToNextAction)
    }
    val isHuaweiLollipop = (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP_MR1 ||
        Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP) &&
        Build.MANUFACTURER.toLowerCase(Locale.getDefault()).contains("huawei")

    if (!isHuaweiLollipop) {
        val mediaStyle = MediaStyle()
                .setCancelButtonIntent(stopPendingIntent)
                .setMediaSession(sessionToken)
                .setShowActionsInCompactView(playPauseIndex)
                .setShowCancelButton(true)

        builder.setStyle(mediaStyle)
    }

    description.iconUri?.let { uri ->
        val largeIcon = CoverCache.getInstance().fetchLargeIfNecessary(context, uri)
        largeIcon?.let { icon -> builder.setLargeIcon(icon) }
    }

    return@async builder.setContentIntent(controller.sessionActivity)
            .setContentText(description.subtitle)
            .setContentTitle(description.title)
            .setDeleteIntent(stopPendingIntent)
            .setOnlyAlertOnce(true)
            .setSmallIcon(R.drawable.ic_stat)
            .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
            .build()
}

我看到这个异常,我认为是相关的:

AndroidRuntime E FATAL EXCEPTION: SysUiBg E Process: com.android.systemui, PID: 26311 E java.lang.SecurityException: Permission Denial: opening provider androidx.core.content.FileProvider from ProcessRecord{410d665 26311:com.android.systemui/u0a141} (pid=26311, uid=10141) that is not exported from UID 10151 E at android.os.Parcel.createExceptionOrNull(Parcel.java:2373) E at android.os.Parcel.createException(Parcel.java:2357) E at android.os.Parcel.readException(Parcel.java:2340) E at android.os.Parcel.readException(Parcel.java:2282) E at android.app.IActivityManager$Stub$Proxy.getContentProvider(IActivityManager.java:5702) E at android.app.ActivityThread.acquireProvider(ActivityThread.java:6813) E at android.app.ContextImpl$ApplicationContentResolver.acquireUnstableProvider(ContextImpl.java:2930) E at android.content.ContentResolver.acquireUnstableProvider(ContentResolver.java:2481) E at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1967) E at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1921) E at android.graphics.ImageDecoder$ContentResolverSource.createImageDecoder(ImageDecoder.java:274) E at android.graphics.ImageDecoder.decodeBitmapImpl(ImageDecoder.java:1862) E at android.graphics.ImageDecoder.decodeBitmap(ImageDecoder.java:1855) E at com.android.systemui.media.MediaDataManager.loadBitmapFromUri(MediaDataManager.kt:462) E at com.android.systemui.media.MediaDataManager.loadBitmapFromUri(MediaDataManager.kt:433) E at com.android.systemui.media.MediaDataManager.loadMediaDataInBg(MediaDataManager.kt:331) E at com.android.systemui.media.MediaDataManager.access$loadMediaDataInBg(MediaDataManager.kt:89) E at com.android.systemui.media.MediaDataManager$loadMediaData$1.run(MediaDataManager.kt:241) E at android.os.Handler.handleCallback(Handler.java:938) E at android.os.Handler.dispatchMessage(Handler.java:99) E at android.os.Looper.loop(Looper.java:223) E at android.os.HandlerThread.run(HandlerThread.java:67) E Caused by: android.os.RemoteException: Remote stack trace: E at com.android.server.am.ActivityManagerService.getContentProviderImpl(ActivityManagerService.java:7155) E at com.android.server.am.ActivityManagerService.getContentProvider(ActivityManagerService.java:7594) E at android.app.IActivityManager$Stub.onTransact(IActivityManager.java:2381) E at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:2883) E at android.os.Binder.execTransactInternal(Binder.java:1159)
如果我删除设置小图标的构建器行,它可以正常工作(但这使得通知只是一个没有媒体样式的普通通知)。您会注意到例外是缺乏从文件提供者获取某些内容的权限,但通知中没有任何内容使用类似的内容。

android notifications
2个回答
1
投票
我发现了问题。由于这是一个 MediaStyle,我们设置 MediaSession,该会话可以访问 MediaMetadataCompat 项。为了构建这些项目,我们有:

val builder = MediaMetadataCompat.Builder() .putString(MediaMetadataCompat.METADATA_KEY_TITLE, doc.title) .putString(MediaMetadataCompat.METADATA_KEY_AUTHOR, doc.author ?: "Unknown") .putString(MediaMetadataCompat.METADATA_KEY_MEDIA_ID, doc.documentId) .putString(MediaMetadataCompat.METADATA_KEY_ALBUM, folders.firstOrNull { it.folderId == doc.folderId }?.folderName) .putString(MediaMetadataCompat.METADATA_KEY_GENRE, sourceType?.name ?: "Unknown") // We don't have Genre info, we'll use for the sourceType .putLong(METADATA_KEY_UAMP_FLAGS, MediaBrowserCompat.MediaItem.FLAG_PLAYABLE.toLong()) if (originalDocumentType != null) { // We don't have a disc no, so builder.putLong(MediaMetadataCompat.METADATA_KEY_DISC_NUMBER, originalDocumentType.ordinal.toLong()) } // we'll use it doc type. if (icon != null) { builder.putString(MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON_URI, icon.toString()) }
最后一行设置 Icon uri。那需要许可。
将其添加到该行的正上方

context.grantUriPermission("com.android.systemui", icon, Intent.FLAG_GRANT_READ_URI_PERMISSION)
现在应用程序可以正常运行了。但由于缺少该权限而导致 Android UI 崩溃的事实仍然是一个错误。我希望无法显示图标,甚至使应用程序崩溃,但肯定不会使 Android 本身崩溃。


0
投票
不幸的是,这个错误仍然是一个问题。我遇到了确切的问题,通知炸毁了电话和您的解决方案

context.grantUriPermission( "com.android.systemui", it.toUri(), Intent.FLAG_GRANT_READ_URI_PERMISSION)

非常有效,谢谢!似乎特定于 Android 11。

我也必须将其添加到我正在开发的音频应用程序的媒体映射器中。

© www.soinside.com 2019 - 2024. All rights reserved.