Notification通知点击无效,无法跳转问题

在Android项目中遇到通知点击无法跳转Activity的问题,通过debug和对比正常demo,发现Notification的声明位置不当导致。将notification声明移动到builder.setContentIntent之后问题解决。同时,设置setSmallIcon才能显示下拉通知图标。问题起因可能是从Eclipse迁移到Studio时,未正确处理setLatestEventInfo的废弃,使用Notification.Builder构建时需注意。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天遇到一个很奇怪的问题,就是我们项目里的通知突然间失效了,具体表现是:通知栏能弹出通知提示,但是想通过它点击跳转到Activity确无法响应,也不消失,然后就抓耳挠腮的开始一点点debug调试找原因所在,始终无所收获。后来我又把项目里的有关通知的代码(一共也没有多少)单独写成一个demo,发现也还是不行。经历了各种百度,查资料,终无所或,后来找了个正常的demo,反复对比,一点点修改实验,终于被我找到了问题所在,下面我就开始讲述一下问题所在。

       首先,先展示一下有问题的代码:

        NotificationManager nm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
        Notification.Builder builder = new Notification.Builder(mContext);
        builder.setContentTitle(title);
        builder.setContentText(content);
        Notification n = builder.getNotification();
        if (PublicUtils.ISDEMO) {
            n.icon = R.drawable.icon_main;
        } else {
            n.icon = R.drawable.icon_main;
        }
        n.tickerText = title;
        if (awoketype == 2) {// isSound表示需要声音提示
            n.defaults |= Notification.DEFAULT_SOUND;// 调用默认声音
        } else if (awoketype == 1) {// 震动
            n.defaults |= Notification.DEFAULT_VIBRATE; // 调用系统默认震动,需要权限
            long[] vibrate = {0, 100, 200, 300}; // 自定义震动
            n.vibrate = vibrate;
        } else {//铃声加震动
            n.defaults |= Notification.DEFAULT_SOUND;// 调用默认声音
            n.defaults |= Notification.DEFAULT_VIBRATE; // 调用系统默认震动,需要权限
            long[] vibrate = {0, 100, 200, 300}; // 自定义震动
            n.vibrate = vibrate;
        }
        // n.sound = Uri.parse("file:///sdcard/test.mp3");//调用自定义声音
        n.defaults |= Notification.DEFAULT_LIGHTS; // 调用系统默认的灯光
        n.flags |= Notification.FLAG_AUTO_CANCEL; // 通知被点击后自动消除
        n.flags |= Notification.FLAG_NO_CLEAR; // 点击'Clear'时,不清除该通知
        //n.flags |= Notification.FLAG_; //让声音、振动无限循环,直到用户响应
        n.when = System.currentTimeMillis();
        Intent intent = new Intent(mContext, RelayActivity.class);
        PendingIntent pi = PendingIntent.getActivity(mContext, id, intent, 0);
        builder.setContentIntent(pi);
        nm.notify(id, n);
问题代码就是这样,具体表现是:通知栏能弹出通知提示,但是想通过它点击跳转到Activity确无法响应,也不消失。

这段代码要是一行一行的去看的话,是一点问题都没有,所以我用debug断点调试许久,发现也没出现问题。百思不得其解,后来就百度了一个正确的demo,然后发现写法都大同小异,为什么我的就有问题呢,细心的我开始一行一行去对比,一点一点去尝试,后来发现我的notification声明的位置跟demo有所不同,然后我就去调换它的位置,把他挪到builder.setContentIntent之后,然后重新运行,奇迹发生了,居然可以了,应该是notification是依附于builder构建的,由于一开始builder的不完整即notification声明位置不恰当导致,问题就这么被解决了。

       另外还要说一点,这样的写法,下拉通知的图标会显示不出来,需要builder.setSmallIcon(R.mipmap.ic_launcher);这样去设置。

     到这里所有的问题都解决了,只是因为以前我们的项目是没有问题的,所以我不明白问题是出在了哪里,我就去以前分支上找答案,我们的项目是最近从eclipse迁移到studio上的,所以我终于在一起eclipse 的分支上发现了点有用的东西,以前分支上的代码是这样的:

     

NotificationManager nm = (NotificationManager)mContext.getSystemService(Context.NOTIFICATION_SERVICE);
		Notification n = new Notification();
		if (PublicUtils.ISDEMO) {
		n.icon = R.drawable.icon_main;
		}else{
			n.icon = R.drawable.icon_main;
		}
		n.tickerText = title;
		if (awoketype == 2) {// isSound表示需要声音提示
			n.defaults |= Notification.DEFAULT_SOUND;// 调用默认声音
		} else if (awoketype == 1) {// 震动
			n.defaults |= Notification.DEFAULT_VIBRATE; // 调用系统默认震动,需要权限
			long[] vibrate = { 0, 100, 200, 300 }; // 自定义震动
			n.vibrate = vibrate;
		}else{//铃声加震动
			n.defaults |= Notification.DEFAULT_SOUND;// 调用默认声音
			n.defaults |= Notification.DEFAULT_VIBRATE; // 调用系统默认震动,需要权限
			long[] vibrate = { 0, 100, 200, 300 }; // 自定义震动
			n.vibrate = vibrate;
		}
		
		// n.sound = Uri.parse("file:///sdcard/test.mp3");//调用自定义声音
		
		n.defaults |= Notification.DEFAULT_LIGHTS; // 调用系统默认的灯光
		
		n.flags |= Notification.FLAG_AUTO_CANCEL; // 通知被点击后自动消除
		n.flags |= Notification.FLAG_NO_CLEAR; // 点击'Clear'时,不清除该通知
		//n.flags |= Notification.FLAG_; //让声音、振动无限循环,直到用户响应
		n.when = System.currentTimeMillis();
		Intent intent = new Intent(mContext, RelayActivity.class);
		PendingIntent pi = PendingIntent.getActivity(mContext, id, intent, 0);
		n.setLatestEventInfo(mContext, title, content, pi);
		nm.notify(id, n);

发现以前的代码顺讯确实是这样,但是有一句话确不同,n.setLatesteEventInfo,我就又去百度这个方法,发现在最新的sdk23上,此方法已失效,原来谷歌废弃了它,所以才用Notification.builder来构建,结果应该是项目迁移的时候,小伙伴直接用Notification.builder进行了替换,而导致这个功能失效,坑了宝宝(/捂脸哭)。

在此写出来,希望大家都长些教训吧,同时也学习了新知识,意外的收获。

  最后贴一下正确的代码:

        NotificationManager nm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
        Notification.Builder builder = new Notification.Builder(mContext);
        builder.setContentTitle(title);
        builder.setContentText(content);
        Intent intent = new Intent(mContext, RelayActivity.class);
        PendingIntent pi = PendingIntent.getActivity(mContext, id, intent, 0);
        builder.setContentIntent(pi);
        builder.setSmallIcon(R.drawable.icon_main);
        Notification n = builder.getNotification();
        if (PublicUtils.ISDEMO) {
            n.icon = R.drawable.icon_main;
        } else {
            n.icon = R.drawable.icon_main;
        }
        n.tickerText = title;
        if (awoketype == 2) {// isSound表示需要声音提示
            n.defaults |= Notification.DEFAULT_SOUND;// 调用默认声音
        } else if (awoketype == 1) {// 震动
            n.defaults |= Notification.DEFAULT_VIBRATE; // 调用系统默认震动,需要权限
            long[] vibrate = {0, 100, 200, 300}; // 自定义震动
            n.vibrate = vibrate;
        } else {//铃声加震动
            n.defaults |= Notification.DEFAULT_SOUND;// 调用默认声音
            n.defaults |= Notification.DEFAULT_VIBRATE; // 调用系统默认震动,需要权限
            long[] vibrate = {0, 100, 200, 300}; // 自定义震动
            n.vibrate = vibrate;
        }
        // n.sound = Uri.parse("file:///sdcard/test.mp3");//调用自定义声音
        n.defaults |= Notification.DEFAULT_LIGHTS; // 调用系统默认的灯光
        n.flags |= Notification.FLAG_AUTO_CANCEL; // 通知被点击后自动消除
        n.flags |= Notification.FLAG_NO_CLEAR; // 点击'Clear'时,不清除该通知
        //n.flags |= Notification.FLAG_; //让声音、振动无限循环,直到用户响应
        n.when = System.currentTimeMillis();
        nm.notify(id, n);


      

<think>好的,我现在需要帮助用户解决Neo系列MediaElement出现Bad notification错误的问题。首先,用户提到的错误信息比较模糊,我需要先理解可能的原因。根据用户提供的引用信息,他们提到了Current_Position变量和跳转播放的逻辑,可能是在处理媒体播放位置时出现了问题。 首先,我应该考虑常见的导致Bad notification错误的原因。通常,这种错误可能与异步操作或线程安全有关。例如,在MediaElement控件中,如果在后台线程更新UI元素而没有正确同步,可能会引发此类异常。用户提到的Current_Position变量可能在非UI线程中被修改,导致通知错误。 接下来,用户代码中可能有类似这样的逻辑:在跳转时设置Current_Position,然后触发某个事件或直接更新MediaElement的位置。如果这部分代码没有正确处理线程调度,比如在异步回调中直接操作UI控件,就可能引发问题。需要检查是否在设置位置时使用了Dispatcher.Invoke来确保在主线程执行。 另外,引用中提到的通过if判断变量是否不为null,可能存在空引用的情况。如果Current_Position在未正确初始化时被访问,也可能导致异常。需要检查变量的初始化时机和空值处理。 还有可能是媒体文件本身的问题,比如格式不支持或损坏,导致MediaElement无法正确解析,从而在尝试跳转时触发错误。用户可能需要检查媒体文件的兼容性,或者尝试其他文件以排除这一因素。 解决方案方面,首先建议用户检查线程使用情况,确保所有对MediaElement的操作都在UI线程执行。其次,验证Current_Position的赋值和空值处理,避免无效值。然后,检查媒体源的有效性,并确保在跳转前媒体已正确加载。最后,考虑更新或修复MediaElement控件,或者查看官方文档是否有相关问题的解决方案。 生成相关问题部分,需要围绕MediaElement的常见错误、线程安全、位置跳转实现以及异常处理等方面展开,帮助用户进一步理解和排查问题。</think>### Neo MediaElement "Bad notification" 错误分析与解决方案 **错误原因分析** 1. **线程异步冲突** MediaElement控件的位置跳转操作涉及UI线程与后台线程的通信。若未使用$Dispatcher.Invoke$方法强制在UI线程执行跳转逻辑,会触发跨线程访问控件的异常[^1]。 2. **无效时间戳赋值** 当$Current\_Position$变量被赋值为负数、超过媒体总时长或非数值类型时,$MediaElement.Position$属性会拒绝非法值并抛出异常。 3. **空引用陷阱** 未正确处理媒体加载状态时,直接访问$Current\_Position$可能导致空引用。建议添加预判逻辑: ```python if Current_Position is not None and media_element.NaturalDuration.HasTimeSpan: target_time = min(max(Current_Position, 0), media_element.NaturalDuration.TimeSpan.TotalSeconds) ``` 4. **媒体源异常** 损坏的媒体文件或特殊编码格式(如HEVC)可能导致解析错误,建议通过$MediaFailed$事件捕获具体错误代码。 **分步解决方案** 1. 强制UI线程执行 在跳转代码外层包裹线程调度: ```python Dispatcher.BeginInvoke((Action)(() => { media_element.Position = TimeSpan.FromSeconds(target_time); })); ``` 2. 添加边界校验 实现安全跳转函数: ```python def safe_seek(position): if media_element.Source is not None and media_element.NaturalDuration.HasTimeSpan: max_duration = media_element.NaturalDuration.TimeSpan.TotalSeconds clamped_position = max(0, min(position, max_duration)) Dispatcher.Invoke(() => media_element.Position = TimeSpan.FromSeconds(clamped_position)) ``` 3. 增强状态监控 注册媒体状态事件: ```python media_element.MediaOpened += (s, e) => { is_media_ready = True }; media_element.CurrentStateChanged += (s, e) => { UpdatePlaybackControls(); }; ``` 4. 安装解码器包 对于Windows N/KN版本,需手动安装[Media Feature Pack](https://support.microsoft.com/help/3145500/media-feature-pack-list-for-windows-10-n-and-windows-10-kn-editions)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值