You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 21:35:38