Android视频锁屏无法暂停及处理电源事件进程闪退求助
问题排查与修复:锁屏/亮屏控制视频播放
问题描述
期望实现:应用内视频播放时,锁屏(按电源键)暂停视频,亮屏恢复播放。当前存在两个问题:
- 锁屏时视频未停止播放
- 处理电源键事件过程中应用出现闪退
现有代码
MainActivity.java 相关片段
@SuppressLint("WrongViewCast") @Override protected void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = ActivityMainBinding.inflate(getLayoutInflater()); setContentView(binding.getRoot()); IntentFilter powerButtonOff = new IntentFilter(Intent.ACTION_SCREEN_OFF); IntentFilter powerButtonOn = new IntentFilter(Intent.ACTION_SCREEN_ON); registerReceiver(powerButtonOnOff, powerButtonOff); registerReceiver(powerButtonOnOff, powerButtonOn); } private void unregisterBroadcast(){ unregisterReceiver(powerButtonOnOff); } BroadcastReceiver powerButtonOnOff = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if(mediaPlayer == null){ mediaPlayer = MediaPlayer.create(context,R.id.videoView); } if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) { try { if (mediaPlayer != null && mediaPlayer.isPlaying()) { mediaPlayer.stop(); mediaPlayer.release(); mediaPlayer = null; } else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) { mediaPlayer.start(); } } catch (Exception e) { e.printStackTrace(); } } } }; @Override protected void onDestroy() { unregisterBroadcast(); }
AndroidManifest.xml 权限部分
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> <uses-permission android:name="android.permission.DEVICE_POWER" tools:ignore="ProtectedPermissions" /> <uses-permission android:name="android.permission.WAKE_LOCK"/>
问题分析与修复方案
1. BroadcastReceiver 逻辑嵌套错误(核心问题)
ACTION_SCREEN_ON的判断被嵌套在ACTION_SCREEN_OFF的if分支内,导致亮屏事件永远无法触发对应的播放逻辑;同时锁屏时直接调用stop()+release()销毁MediaPlayer,亮屏时mediaPlayer已为null,调用start()会触发空指针异常导致闪退。
2. MediaPlayer 初始化参数错误
MediaPlayer.create(context, R.id.videoView)用法错误,create方法的第二个参数应为音频/视频资源ID(如R.raw.video),而非View的ID。如果使用VideoView,直接操作VideoView的API会更稳定。
3. Activity生命周期方法缺失
onDestroy中未调用super.onDestroy(),会破坏Activity的生命周期流程,引发潜在异常。
4. Receiver注册/注销风险
两次调用registerReceiver注册同一个Receiver,注销时仅调用一次unregisterReceiver,后续可能触发IllegalArgumentException(Receiver未注册)。可合并IntentFilter,只注册一次。
5. 冗余权限清理
DEVICE_POWER是系统级保护权限,第三方应用无法获取,可直接移除;RECEIVE_BOOT_COMPLETED与当前需求无关,也可删除。
修复后的代码示例
MainActivity.java
@SuppressLint("WrongViewCast") @Override protected void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = ActivityMainBinding.inflate(getLayoutInflater()); setContentView(binding.getRoot()); // 合并IntentFilter,单次注册Receiver IntentFilter screenFilter = new IntentFilter(); screenFilter.addAction(Intent.ACTION_SCREEN_OFF); screenFilter.addAction(Intent.ACTION_SCREEN_ON); registerReceiver(powerButtonOnOff, screenFilter); // 初始化VideoView(替换为你的视频路径/URI) binding.videoView.setVideoPath("android.resource://" + getPackageName() + "/" + R.raw.your_video); } private void unregisterBroadcast(){ try { unregisterReceiver(powerButtonOnOff); } catch (IllegalArgumentException e) { // 捕获Receiver未注册的异常,避免崩溃 e.printStackTrace(); } } BroadcastReceiver powerButtonOnOff = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (intent == null || intent.getAction() == null) return; VideoView videoView = binding.videoView; if (Intent.ACTION_SCREEN_OFF.equals(intent.getAction())) { // 锁屏时暂停视频,保留MediaPlayer状态 if (videoView.isPlaying()) { videoView.pause(); } } else if (Intent.ACTION_SCREEN_ON.equals(intent.getAction())) { // 亮屏时恢复播放 if (!videoView.isPlaying()) { videoView.start(); } } } }; @Override protected void onDestroy() { unregisterBroadcast(); super.onDestroy(); // 必须调用父类生命周期方法 }
AndroidManifest.xml 精简权限
<uses-permission android:name="android.permission.WAKE_LOCK"/> <!-- 若视频来自网络,需添加网络权限 --> <!-- <uses-permission android:name="android.permission.INTERNET"/> -->
额外建议
- 直接使用
VideoView的pause()/start()API,无需手动管理MediaPlayer,可避免生命周期管理错误。 - Android 8.0+ 中静态注册的BroadcastReceiver无法监听
ACTION_SCREEN_ON/OFF,当前使用动态注册是正确的。 - 锁屏时选择暂停而非销毁MediaPlayer,可保留播放进度,提升用户体验。
内容的提问来源于stack exchange,提问作者Chae Seong Lim
相关产品推荐
相关产品推荐

